diff --git a/DEPS b/DEPS index 96fd4573..278e159 100644 --- a/DEPS +++ b/DEPS
@@ -209,11 +209,11 @@ # 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': 'c28336e5c272b7cd39263bcd43e0174a29d08be8', + 'skia_revision': '2e04df9a06411b8c67047418d84144592766ef64', # 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': '6b19a1e0f50069572829af1dac192ecc744ae25f', + 'v8_revision': '442eb43d992f607b483f21c1a3d6065a2099d1ce', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -566,7 +566,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '84b83bdb8bf34172214876305a9fcc9ae5436b47', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'd5d2306bc8fe1f61b31c773188a0bd32994c5351', 'condition': 'checkout_ios', }, @@ -1306,7 +1306,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '91b4f68052b4d97bd4c803605b7f9577be2f0410', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'acb2e677b426b56b2a6c8a82b5e273aa11916666', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1384,7 +1384,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'b2zF96vg3VSaAN9mPGE7apzfGOnnijkrxePPj4UuD08C' + 'version': 'YPJlUd3Zs4_ILtYWK6Nl_fXxu9dlEi-67lPCAVLnWbMC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1542,7 +1542,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '340098b7d4f735690f433daafc5585ad6d3c51be', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '2072b87261a6505a88561bdeab3e7405d7038eaa', + Var('webrtc_git') + '/src.git' + '@' + '5254e429e44c88ee112f20cc11ef745bd53cc203', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1614,7 +1614,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@bfa5b1808eba0f0fca7e3d25895615e1fe298eae', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@88aa98bf3ab602c9e478ee69986ff31798f5cbc6', 'condition': 'checkout_src_internal', },
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index d42d366..70d43ab 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -2442,6 +2442,7 @@ ":test_support", "//ash/app_list", "//ash/app_list:test_support", + "//ash/app_list:unit_tests", "//ash/app_menu", "//ash/assistant/model", "//ash/assistant/ui",
diff --git a/ash/app_list/BUILD.gn b/ash/app_list/BUILD.gn index ff83a1f..4e296191 100644 --- a/ash/app_list/BUILD.gn +++ b/ash/app_list/BUILD.gn
@@ -209,12 +209,11 @@ ] } -test("app_list_unittests") { - use_xvfb = use_xvfb_in_this_config +source_set("unit_tests") { + testonly = true sources = [ "folder_image_unittest.cc", - "test/run_all_unittests.cc", "views/app_list_main_view_unittest.cc", "views/app_list_menu_model_adapter_unittest.cc", "views/app_list_view_unittest.cc", @@ -262,3 +261,17 @@ "//ui/resources:ui_test_pak_data", ] } + +# TODO(https://crbug.com/942564): Remove this binary from the bots and then +# delete it. +test("app_list_unittests") { + use_xvfb = use_xvfb_in_this_config + + sources = [ "test/run_all_unittests.cc" ] + + deps = [ + "//base", + "//base/test:test_support", + "//testing/gtest", + ] +}
diff --git a/ash/app_list/test/run_all_unittests.cc b/ash/app_list/test/run_all_unittests.cc index 2d15995..9598326 100644 --- a/ash/app_list/test/run_all_unittests.cc +++ b/ash/app_list/test/run_all_unittests.cc
@@ -2,76 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "base/bind.h" -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/path_service.h" #include "base/test/launcher/unit_test_launcher.h" -#include "base/test/test_discardable_memory_allocator.h" #include "base/test/test_suite.h" -#include "build/build_config.h" -#include "mojo/core/embedder/embedder.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/aura/env.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/ui_base_paths.h" -#include "ui/gl/test/gl_surface_test_support.h" namespace { -// Use the pattern established in content_switches.h, but don't add a content -// dependency -- app list shouldn't have one. -const char kTestType[] = "test-type"; - -class AppListTestSuite : public base::TestSuite { - public: - AppListTestSuite(int argc, char** argv) : base::TestSuite(argc, argv) {} - - protected: - void Initialize() override { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII(kTestType, "applist"); - - base::TestSuite::Initialize(); - gl::GLSurfaceTestSupport::InitializeOneOff(); - ui::RegisterPathProvider(); - - base::FilePath ui_test_pak_path; - ASSERT_TRUE(base::PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path)); - ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path); - - base::DiscardableMemoryAllocator::SetInstance( - &discardable_memory_allocator_); - app_list_color_provider_ = - std::make_unique<ash::TestAppListColorProvider>(); - env_ = aura::Env::CreateInstance(); - } - - void Shutdown() override { - env_.reset(); - app_list_color_provider_.reset(); - ui::ResourceBundle::CleanupSharedInstance(); - base::TestSuite::Shutdown(); - } - - private: - std::unique_ptr<aura::Env> env_; - base::TestDiscardableMemoryAllocator discardable_memory_allocator_; - std::unique_ptr<ash::TestAppListColorProvider> app_list_color_provider_; - - DISALLOW_COPY_AND_ASSIGN(AppListTestSuite); -}; +// An empty test so that the test runner has something to run. +TEST(EmptyTest, Empty) {} } // namespace +// TODO(https://crbug.com/942564): Remove this test suite from the bots and then +// delete it. For now we run a stub suite so we can do the removal in a separate +// CL. int main(int argc, char** argv) { - AppListTestSuite test_suite(argc, argv); - - mojo::core::Init(); + base::TestSuite test_suite(argc, argv); return base::LaunchUnitTests( argc, argv, - base::BindOnce(&AppListTestSuite::Run, base::Unretained(&test_suite))); + base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite))); }
diff --git a/ash/app_list/views/app_list_main_view_unittest.cc b/ash/app_list/views/app_list_main_view_unittest.cc index 98e20d37..85b9269 100644 --- a/ash/app_list/views/app_list_main_view_unittest.cc +++ b/ash/app_list/views/app_list_main_view_unittest.cc
@@ -16,6 +16,7 @@ #include "ash/app_list/views/page_switcher.h" #include "ash/app_list/views/search_box_view.h" #include "ash/app_list/views/test/apps_grid_view_test_api.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "ui/events/base_event_utils.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/test/views_test_base.h" @@ -211,6 +212,7 @@ } protected: + TestAppListColorProvider color_provider_; // Needed by AppListView. AppListView* app_list_view_ = nullptr; // Owned by native widget. std::unique_ptr<AppListTestViewDelegate> delegate_; };
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc index faabf40..cdf531e 100644 --- a/ash/app_list/views/app_list_view_unittest.cc +++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -44,6 +44,7 @@ #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/pagination/pagination_model.h" #include "ash/public/cpp/presentation_time_recorder.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "ash/search_box/search_box_constants.h" #include "base/macros.h" #include "base/run_loop.h" @@ -390,6 +391,8 @@ // Restores the locale to default when destructor is called. base::test::ScopedRestoreICUDefaultLocale restore_locale_; + TestAppListColorProvider color_provider_; // Needed by AppListView. + AppListView* view_ = nullptr; // Owned by native widget. std::unique_ptr<AppListTestViewDelegate> delegate_; std::unique_ptr<AppsGridViewTestApi> test_api_; @@ -809,6 +812,7 @@ base::test::ScopedFeatureList scoped_feature_list_; private: + TestAppListColorProvider color_provider_; // Needed by AppListView. AppListView* view_ = nullptr; // Owned by native widget. SearchResultContainerView* suggestions_container_ = nullptr; // Owned by view hierarchy.
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index 938c839..a291a5f 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -36,6 +36,7 @@ #include "ash/public/cpp/app_list/app_list_switches.h" #include "ash/public/cpp/pagination/pagination_model.h" #include "ash/public/cpp/presentation_time_recorder.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/macros.h" @@ -512,6 +513,7 @@ apps_grid_view_->MoveItemInModel(item_view, target); } + TestAppListColorProvider color_provider_; // Needed by AppListView. AppListView* app_list_view_ = nullptr; // Owned by native widget. AppsGridView* apps_grid_view_ = nullptr; // Owned by |app_list_view_|. ContentsView* contents_view_ = nullptr; // Owned by |app_list_view_|.
diff --git a/ash/app_list/views/folder_header_view_unittest.cc b/ash/app_list/views/folder_header_view_unittest.cc index 6bbc932c..636e60d 100644 --- a/ash/app_list/views/folder_header_view_unittest.cc +++ b/ash/app_list/views/folder_header_view_unittest.cc
@@ -16,6 +16,7 @@ #include "ash/app_list/test/app_list_test_model.h" #include "ash/app_list/views/folder_header_view_delegate.h" #include "ash/public/cpp/app_list/app_list_config.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/macros.h" @@ -63,8 +64,8 @@ class FolderHeaderViewTest : public views::ViewsTestBase { public: - FolderHeaderViewTest() {} - ~FolderHeaderViewTest() override {} + FolderHeaderViewTest() = default; + ~FolderHeaderViewTest() override = default; // testing::Test overrides: void SetUp() override { @@ -118,6 +119,7 @@ folder_header_view_->SetPreviousFolderNameForTest(previous_name); } + TestAppListColorProvider color_provider_; // Needed by AppListView. std::unique_ptr<AppListTestModel> model_; FolderHeaderView* folder_header_view_ = nullptr; // owned by |widget_|. std::unique_ptr<TestFolderHeaderViewDelegate> delegate_;
diff --git a/ash/app_list/views/privacy_container_view_unittest.cc b/ash/app_list/views/privacy_container_view_unittest.cc index 3431a62..9840e629 100644 --- a/ash/app_list/views/privacy_container_view_unittest.cc +++ b/ash/app_list/views/privacy_container_view_unittest.cc
@@ -8,6 +8,7 @@ #include "ash/app_list/test/app_list_test_view_delegate.h" #include "ash/app_list/views/suggested_content_info_view.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "ui/views/test/views_test_base.h" namespace ash { @@ -34,6 +35,7 @@ } private: + TestAppListColorProvider color_provider_; // Needed by AppListView. AppListTestViewDelegate view_delegate_; std::unique_ptr<PrivacyContainerView> view_; };
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index bf456a9..572ed55 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -19,6 +19,7 @@ #include "ash/app_list/views/search_result_page_view.h" #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/vector_icons/vector_icons.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "ash/search_box/search_box_constants.h" #include "ash/search_box/search_box_view_delegate.h" #include "base/macros.h" @@ -181,6 +182,7 @@ void ActiveChanged(SearchBoxViewBase* sender) override {} void SearchBoxFocusChanged(SearchBoxViewBase* sender) override {} + TestAppListColorProvider color_provider_; // Needed by AppListView. AppListTestViewDelegate view_delegate_; views::Widget* widget_; AppListView* app_list_view_ = nullptr;
diff --git a/ash/app_list/views/search_result_list_view_unittest.cc b/ash/app_list/views/search_result_list_view_unittest.cc index 6a524da2..d193007 100644 --- a/ash/app_list/views/search_result_list_view_unittest.cc +++ b/ash/app_list/views/search_result_list_view_unittest.cc
@@ -15,6 +15,7 @@ #include "ash/app_list/test/test_search_result.h" #include "ash/app_list/views/search_result_view.h" #include "ash/public/cpp/app_list/app_list_features.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -133,6 +134,7 @@ } private: + TestAppListColorProvider color_provider_; // Needed by AppListView. AppListTestViewDelegate view_delegate_; std::unique_ptr<SearchResultListView> view_; views::Widget* widget_;
diff --git a/ash/app_list/views/search_result_page_view_unittest.cc b/ash/app_list/views/search_result_page_view_unittest.cc index 335ac4f..ce08889 100644 --- a/ash/app_list/views/search_result_page_view_unittest.cc +++ b/ash/app_list/views/search_result_page_view_unittest.cc
@@ -18,6 +18,7 @@ #include "ash/app_list/views/search_result_tile_item_list_view.h" #include "ash/app_list/views/search_result_view.h" #include "ash/public/cpp/app_list/app_list_features.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -68,6 +69,7 @@ } private: + TestAppListColorProvider color_provider_; // Needed by AppListView. AppListView* app_list_view_ = nullptr; // Owned by native widget. SearchResultPageView* view_ = nullptr; // Owned by views hierarchy. SearchResultTileItemListView* tile_list_view_ =
diff --git a/ash/app_list/views/search_result_tile_item_list_view_unittest.cc b/ash/app_list/views/search_result_tile_item_list_view_unittest.cc index 2aeced82..ba7e657a 100644 --- a/ash/app_list/views/search_result_tile_item_list_view_unittest.cc +++ b/ash/app_list/views/search_result_tile_item_list_view_unittest.cc
@@ -14,6 +14,7 @@ #include "ash/app_list/views/search_result_tile_item_view.h" #include "ash/app_list/views/search_result_view.h" #include "ash/public/cpp/app_list/app_list_features.h" +#include "ash/public/cpp/test/test_app_list_color_provider.h" #include "base/macros.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -194,6 +195,7 @@ size_t GetResultCount() const { return view_->num_results(); } private: + TestAppListColorProvider color_provider_; // Needed by AppListView. test::AppListTestViewDelegate view_delegate_; std::unique_ptr<SearchResultTileItemListView> view_; views::Widget* widget_;
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 26bf341..5f1eb44 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -2980,9 +2980,6 @@ <message name="IDS_ASH_ASSISTANT_ONBOARDING_SUGGESTION_TECHNICAL" desc="Message shown in an onboarding suggestion in Assistant UI to initiate a technical query."> Take a screenshot </message> - <message name="IDS_ASSISTANT_TIMER_NOTIFICATION_TITLE" desc="Title for Assistant timer notification."> - Time's up - </message> <message name="IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE" desc="Message for Assistant timer notification. Example: 10m timer."> <ph name="TOTAL_TIME">{0}<ex>10m</ex></ph> timer </message> @@ -3516,6 +3513,10 @@ <message name="IDS_ASH_SHORTCUT_DEPRECATION_ALT_CLICK" desc="Message telling user to use search/launcher click instead of alt click to emulate a right click. The name of the launcher key varies by device and may be either Search or Launcher depending on the glyph on the keyboard." translateable="false"> The Alt + click keyboard shortcut has changed. To use your keyboard to right-click, press the <ph name="LAUNCHER_KEY_NAME">$1<ex>Launcher</ex></ph> key + click. </message> + <message name="IDS_ASH_SHORTCUT_DEPRECATION_FKEY" desc="Message telling user to use search/launcher + top row key instead of Search + a digit key to emulate a F-Key. The name of the launcher key varies by device and may be either Search or Launcher depending on the glyph on the keyboard." translateable="false"> + The Search + Digit keyboard shortcut has changed. To generate F-Keys, press the <ph name="LAUNCHER_KEY_NAME">$1<ex>Launcher</ex></ph> key + a key on the top row. + </message> + <!-- PciePeripheral notifications --> <message name="IDS_ASH_PCIE_PERIPHERAL_NOTIFICATION_PERFORMANCE_LIMITED_TITLE" desc="Notification title to indicate to users that their peripheral device's performance may be limited.">
diff --git a/ash/assistant/assistant_alarm_timer_controller_impl.cc b/ash/assistant/assistant_alarm_timer_controller_impl.cc index f774024f..e0ee2c71 100644 --- a/ash/assistant/assistant_alarm_timer_controller_impl.cc +++ b/ash/assistant/assistant_alarm_timer_controller_impl.cc
@@ -38,7 +38,6 @@ using chromeos::assistant::AssistantNotificationPriority; using chromeos::assistant::AssistantTimer; using chromeos::assistant::AssistantTimerState; -using chromeos::assistant::features::IsTimersV2Enabled; // Grouping key and ID prefix for timer notifications. constexpr char kTimerNotificationGroupingKey[] = "assistant/timer"; @@ -74,15 +73,15 @@ // We only show |hours| if necessary. if (hours) - measures.push_back(icu::Measure(hours, createHour(status), status)); + measures.emplace_back(hours, createHour(status), status); // We only show |minutes| if necessary or if using numeric format |width|. if (minutes || width == UMEASFMT_WIDTH_NUMERIC) - measures.push_back(icu::Measure(minutes, createMinute(status), status)); + measures.emplace_back(minutes, createMinute(status), status); // We only show |seconds| if necessary or if using numeric format |width|. if (seconds || width == UMEASFMT_WIDTH_NUMERIC) - measures.push_back(icu::Measure(seconds, createSecond(status), status)); + measures.emplace_back(seconds, createSecond(status), status); // Format our |measures| into a |unicode_message|. icu::UnicodeString unicode_message; @@ -137,42 +136,26 @@ // Creates a notification title for the given |timer|. std::string CreateTimerNotificationTitle(const AssistantTimer& timer) { - if (IsTimersV2Enabled()) - return ToRemainingTimeString(timer); - return l10n_util::GetStringUTF8(IDS_ASSISTANT_TIMER_NOTIFICATION_TITLE); + return ToRemainingTimeString(timer); } // Creates a notification message for the given |timer|. std::string CreateTimerNotificationMessage(const AssistantTimer& timer) { - if (IsTimersV2Enabled()) { - if (timer.label.empty()) { - return base::UTF16ToUTF8( - base::i18n::MessageFormatter::FormatWithNumberedArgs( - l10n_util::GetStringUTF16( - timer.state == AssistantTimerState::kFired - ? IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE_WHEN_FIRED - : IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE), - ToOriginalDurationString(timer))); - } - return base::UTF16ToUTF8(base::i18n::MessageFormatter::FormatWithNumberedArgs( - l10n_util::GetStringUTF16( - timer.state == AssistantTimerState::kFired - ? IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE_WHEN_FIRED_WITH_LABEL - : IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE_WITH_LABEL), - ToOriginalDurationString(timer), timer.label)); + if (timer.label.empty()) { + return base::UTF16ToUTF8( + base::i18n::MessageFormatter::FormatWithNumberedArgs( + l10n_util::GetStringUTF16( + timer.state == AssistantTimerState::kFired + ? IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE_WHEN_FIRED + : IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE), + ToOriginalDurationString(timer))); } - return ToRemainingTimeString(timer); -} - -// Creates notification action URL for the given |timer|. -GURL CreateTimerNotificationActionUrl(const AssistantTimer& timer) { - // In timers v2, clicking the notification does nothing. - if (IsTimersV2Enabled()) - return GURL(); - // In timers v1, clicking the notification removes the |timer|. - return assistant::util::CreateAlarmTimerDeepLink( - AlarmTimerAction::kRemoveAlarmOrTimer, timer.id) - .value(); + return base::UTF16ToUTF8(base::i18n::MessageFormatter::FormatWithNumberedArgs( + l10n_util::GetStringUTF16( + timer.state == AssistantTimerState::kFired + ? IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE_WHEN_FIRED_WITH_LABEL + : IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE_WITH_LABEL), + ToOriginalDurationString(timer), timer.label)); } // Creates notification buttons for the given |timer|. @@ -180,29 +163,6 @@ const AssistantTimer& timer) { std::vector<AssistantNotificationButton> buttons; - if (!IsTimersV2Enabled()) { - // "STOP" button. - buttons.push_back( - {l10n_util::GetStringUTF8(IDS_ASSISTANT_TIMER_NOTIFICATION_STOP_BUTTON), - assistant::util::CreateAlarmTimerDeepLink( - AlarmTimerAction::kRemoveAlarmOrTimer, timer.id) - .value(), - /*remove_notification_on_click=*/true}); - - // "ADD 1 MIN" button. - buttons.push_back({l10n_util::GetStringUTF8( - IDS_ASSISTANT_TIMER_NOTIFICATION_ADD_1_MIN_BUTTON), - assistant::util::CreateAlarmTimerDeepLink( - AlarmTimerAction::kAddTimeToTimer, timer.id, - base::TimeDelta::FromMinutes(1)) - .value(), - /*remove_notification_on_click=*/true}); - - return buttons; - } - - DCHECK(IsTimersV2Enabled()); - if (timer.state != AssistantTimerState::kFired) { if (timer.state == AssistantTimerState::kPaused) { // "RESUME" button. @@ -256,10 +216,6 @@ // Creates a timer notification priority for the given |timer|. AssistantNotificationPriority CreateTimerNotificationPriority( const AssistantTimer& timer) { - // In timers v1, all notifications are |kHigh| priority. - if (!IsTimersV2Enabled()) - return AssistantNotificationPriority::kHigh; - // In timers v2, a notification for a |kFired| timer is |kHigh| priority. // This will cause the notification to pop up to the user. if (timer.state == AssistantTimerState::kFired) @@ -286,13 +242,12 @@ AssistantNotification notification; notification.title = CreateTimerNotificationTitle(timer); notification.message = CreateTimerNotificationMessage(timer); - notification.action_url = CreateTimerNotificationActionUrl(timer); notification.buttons = CreateTimerNotificationButtons(timer); notification.client_id = CreateTimerNotificationId(timer); notification.grouping_key = kTimerNotificationGroupingKey; notification.priority = CreateTimerNotificationPriority(timer); - notification.remove_on_click = !IsTimersV2Enabled(); - notification.is_pinned = IsTimersV2Enabled(); + notification.remove_on_click = false; + notification.is_pinned = true; // If we are creating a notification to replace an |existing_notification| and // our new notification has higher priority, we want the system to "renotify" @@ -313,11 +268,6 @@ // If |id| is not equal, then |update| does refer to the |original| timer. DCHECK_EQ(original.id, update.id); - // In v1, LibAssistant updates are always allowed since we only ever manage a - // single timer at a time and only as it transitions from firing to removal. - if (!IsTimersV2Enabled()) - return true; - // In v2, updates are only allowed from LibAssistant if they are significant. // We may receive an update due to a state change in another timer, and we'd // want to discard the update to this timer to avoid introducing UI jank by
diff --git a/ash/assistant/assistant_alarm_timer_controller_unittest.cc b/ash/assistant/assistant_alarm_timer_controller_unittest.cc index 7ef970b..4f867a3 100644 --- a/ash/assistant/assistant_alarm_timer_controller_unittest.cc +++ b/ash/assistant/assistant_alarm_timer_controller_unittest.cc
@@ -96,7 +96,7 @@ } protected: - TimerEvent(const std::string& id, AssistantTimerState state) : timer_() { + TimerEvent(const std::string& id, AssistantTimerState state) { timer_.id = id; timer_.state = state; timer_.fire_time = base::Time::Now(); @@ -336,8 +336,6 @@ // AshTestBase: void SetUp() override { AssistantAshTestBase::SetUp(); - feature_list_.InitAndDisableFeature( - chromeos::assistant::features::kAssistantTimersV2); } void TearDown() override { @@ -371,8 +369,6 @@ } private: - base::test::ScopedFeatureList feature_list_; - DISALLOW_COPY_AND_ASSIGN(AssistantAlarmTimerControllerTest); }; @@ -410,73 +406,9 @@ controller()->GetModel()->RemoveObserver(&mock); } -// Tests that creation time is properly respected/carried forward when updating -// a timer. -TEST_F(AssistantAlarmTimerControllerTest, UpdatedTimersShouldHaveCreationTime) { - MockAssistantAlarmTimerModelObserver mock; - controller()->GetModel()->AddObserver(&mock); - - base::Time creation_time = base::Time::Now(); - - // Schedule a timer w/ specified |creation_time|. - ScheduleTimer(kTimerId).WithCreationTime(creation_time); - - // Advance clock. - AdvanceClockAndWaitForTimerUpdate(base::TimeDelta::FromMinutes(1)); - - // If unspecified, |creation_time| should carry forward on update. - EXPECT_CALL(mock, OnTimerUpdated) - .WillOnce(testing::Invoke([&](const AssistantTimer& timer) { - EXPECT_NE(creation_time, base::Time::Now()); - EXPECT_EQ(creation_time, timer.creation_time.value()); - })); - - // Update timer w/o specifying |creation_time|. - ScheduleTimer{kTimerId}; - - // Reset for the next test case. - testing::Mock::VerifyAndClearExpectations(&mock); - - // If specified, |creation_time| should be respected. - creation_time += base::TimeDelta::FromHours(1); - EXPECT_CALL(mock, OnTimerUpdated) - .WillOnce(testing::Invoke([&](const AssistantTimer& timer) { - EXPECT_EQ(creation_time, timer.creation_time.value()); - })); - - // Update timer w/ specified |creation_time|. - ScheduleTimer(kTimerId).WithCreationTime(creation_time); - - controller()->GetModel()->RemoveObserver(&mock); -} - -// Tests that a notification is added for a timer and has the expected title. -// NOTE: This test is only applicable to timers v1. -TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedTitle) { - ASSERT_FALSE(chromeos::assistant::features::IsTimersV2Enabled()); - - // Observe notifications. - ScopedNotificationModelObserver observer; - - // Fire a timer. - FireTimer{kTimerId}; - - // We expect that a notification exists w/ an internationalized title. - EXPECT_EQ(ExpectedNotification().WithClientId(kClientId).WithTitleId( - IDS_ASSISTANT_TIMER_NOTIFICATION_TITLE), - observer.last_notification()); -} - // Tests that a notification is added for a timer and has the expected title at // various states in its lifecycle. -// NOTE: This test is only applicable to timers v2. -TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedTitleV2) { - // Enable timers v2. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - chromeos::assistant::features::kAssistantTimersV2); - ASSERT_TRUE(chromeos::assistant::features::IsTimersV2Enabled()); - +TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedTitle) { // We're going to run our test over a few locales to ensure i18n compliance. std::vector<I18nTestCase> i18n_test_cases; @@ -535,73 +467,9 @@ } } -// Tests that a notification is added for a timer and has the expected message -// at various states in its lifecycle. -// NOTE: This test is only applicable to timers v1. -TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedMessage) { - ASSERT_FALSE(chromeos::assistant::features::IsTimersV2Enabled()); - - // We're going to run our test over a few locales to ensure i18n compliance. - std::vector<I18nTestCase> i18n_test_cases; - - // We'll test in English (United States). - i18n_test_cases.push_back({ - /*locale=*/"en_US", - /*ticks=*/ - { - {base::TimeDelta(), "0:00"}, - {base::TimeDelta::FromSeconds(1), "-0:01"}, - {base::TimeDelta::FromMinutes(1), "-1:01"}, - {base::TimeDelta::FromHours(1), "-1:01:01"}, - }, - }); - - // We'll also test in Slovenian (Slovenia). - i18n_test_cases.push_back({ - /*locale=*/"sl_SI", - /*ticks=*/ - { - {base::TimeDelta(), "0.00"}, - {base::TimeDelta::FromSeconds(1), "-0.01"}, - {base::TimeDelta::FromMinutes(1), "-1.01"}, - {base::TimeDelta::FromHours(1), "-1.01.01"}, - }, - }); - - // Run all of our internationalized test cases. - for (auto& i18n_test_case : i18n_test_cases) { - base::test::ScopedRestoreICUDefaultLocale locale(i18n_test_case.locale); - - // Observe notifications. - ScopedNotificationModelObserver observer; - - // Fire a timer. - FireTimer{kTimerId}; - - // Run each tick of the clock in the test. - for (auto& tick : i18n_test_case.ticks) { - // Advance clock to next tick. - AdvanceClockAndWaitForTimerUpdate(tick.advance_clock); - - // Make assertions about the notification. - EXPECT_EQ(ExpectedNotification().WithClientId(kClientId).WithMessage( - tick.expected_string), - observer.last_notification()); - } - } -} - // TODO(dmblack): Add another locale after string translation. // Tests that a notification is added for a timer and has the expected message. -// NOTE: This test is only applicable to timers v2. -TEST_F(AssistantAlarmTimerControllerTest, - TimerNotificationHasExpectedMessageV2) { - // Enable timers v2. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - chromeos::assistant::features::kAssistantTimersV2); - ASSERT_TRUE(chromeos::assistant::features::IsTimersV2Enabled()); - +TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedMessage) { constexpr char kEmptyLabel[] = ""; constexpr base::TimeDelta kOneSec = base::TimeDelta::FromSeconds(1); constexpr base::TimeDelta kOneMin = base::TimeDelta::FromMinutes(1); @@ -672,35 +540,7 @@ } // Tests that a notification is added for a timer and has the expected action. -// NOTE: This test is only applicable to timers v1. TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedAction) { - ASSERT_FALSE(chromeos::assistant::features::IsTimersV2Enabled()); - - // Observe notifications. - ScopedNotificationModelObserver observer; - - // Fire a timer. - FireTimer{kTimerId}; - - // We expect that the notification action will cause removal of the timer. - EXPECT_EQ( - ExpectedNotification().WithClientId(kClientId).WithActionUrl( - assistant::util::CreateAlarmTimerDeepLink( - assistant::util::AlarmTimerAction::kRemoveAlarmOrTimer, kTimerId) - .value()), - observer.last_notification()); -} - -// Tests that a notification is added for a timer and has the expected action. -// NOTE: This test is only applicable to timers v2. -TEST_F(AssistantAlarmTimerControllerTest, - TimerNotificationHasExpectedActionV2) { - // Enable timers v2. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - chromeos::assistant::features::kAssistantTimersV2); - ASSERT_TRUE(chromeos::assistant::features::IsTimersV2Enabled()); - // Observe notifications. ScopedNotificationModelObserver observer; @@ -713,55 +553,9 @@ observer.last_notification()); } -// Tests that a notification is added when a timer is fired and has the expected -// buttons. -// NOTE: This test is only applicable to timers v1. -TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedButtons) { - ASSERT_FALSE(chromeos::assistant::features::IsTimersV2Enabled()); - - // Observe notifications. - ScopedNotificationModelObserver observer; - - // Fire a timer. - FireTimer{kTimerId}; - - // We expect the timer notification to have two buttons. - ASSERT_EQ(2u, observer.last_notification().buttons.size()); - - // We expect a "STOP" button which will remove the timer. - EXPECT_EQ(ExpectedButton() - .WithLabel(IDS_ASSISTANT_TIMER_NOTIFICATION_STOP_BUTTON) - .WithActionUrl( - assistant::util::CreateAlarmTimerDeepLink( - assistant::util::AlarmTimerAction::kRemoveAlarmOrTimer, - kTimerId) - .value()) - .WithRemoveNotificationOnClick(true), - observer.last_notification().buttons.at(0)); - - // We expect an "ADD 1 MIN" button which will add time to the timer. - EXPECT_EQ( - ExpectedButton() - .WithLabel(IDS_ASSISTANT_TIMER_NOTIFICATION_ADD_1_MIN_BUTTON) - .WithActionUrl(assistant::util::CreateAlarmTimerDeepLink( - assistant::util::AlarmTimerAction::kAddTimeToTimer, - kTimerId, base::TimeDelta::FromMinutes(1)) - .value()) - .WithRemoveNotificationOnClick(true), - observer.last_notification().buttons.at(1)); -} - // Tests that a notification is added for a timer and has the expected buttons // at each state in its lifecycle. -// NOTE: This test is only applicable to timers v2. -TEST_F(AssistantAlarmTimerControllerTest, - TimerNotificationHasExpectedButtonsV2) { - // Enable timers v2. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - chromeos::assistant::features::kAssistantTimersV2); - ASSERT_TRUE(chromeos::assistant::features::IsTimersV2Enabled()); - +TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedButtons) { // Observe notifications. ScopedNotificationModelObserver observer; @@ -853,35 +647,9 @@ } // Tests that a notification is added for a timer and has the expected value to -// cause removal on click. -// NOTE: This test is only applicable to timers v1. +// *not* cause removal on click. TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedRemoveOnClick) { - ASSERT_FALSE(chromeos::assistant::features::IsTimersV2Enabled()); - - // Observe notifications. - ScopedNotificationModelObserver observer; - - // Fire a timer. - FireTimer{kTimerId}; - - // Make assertions about the notification. - EXPECT_EQ( - ExpectedNotification().WithClientId(kClientId).WithRemoveOnClick(true), - observer.last_notification()); -} - -// Tests that a notification is added for a timer and has the expected value to -// *not* cause removal on click. -// Note: This test is only applicable to timers v2. -TEST_F(AssistantAlarmTimerControllerTest, - TimerNotificationHasExpectedRemoveOnClickV2) { - // Enable timers v2. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - chromeos::assistant::features::kAssistantTimersV2); - ASSERT_TRUE(chromeos::assistant::features::IsTimersV2Enabled()); - // Observe notifications. ScopedNotificationModelObserver observer; @@ -895,34 +663,9 @@ } // Tests that a notification is added for a timer and has the expected value to -// *not* cause renotification. -// NOTE: This test is only applicable to timers v1. +// cause renotification. TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationHasExpectedRenotify) { - ASSERT_FALSE(chromeos::assistant::features::IsTimersV2Enabled()); - - // Observe notifications. - ScopedNotificationModelObserver observer; - - // Fire a timer. - FireTimer{kTimerId}; - - // Make assertions about the notification. - EXPECT_EQ(ExpectedNotification().WithClientId(kClientId).WithRenotify(false), - observer.last_notification()); -} - -// Tests that a notification is added for a timer and has the expected value to -// cause renotification. -// Note: This test is only applicable to timers v2. -TEST_F(AssistantAlarmTimerControllerTest, - TimerNotificationHasExpectedRenotifyV2) { - // Enable timers v2. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - chromeos::assistant::features::kAssistantTimersV2); - ASSERT_TRUE(chromeos::assistant::features::IsTimersV2Enabled()); - // Observe notifications. ScopedNotificationModelObserver observer; @@ -941,35 +684,10 @@ observer.last_notification()); } -// Tests that a notification is added for a timer and has the expected priority. -// NOTE: This test is only applicable to timers v1. -TEST_F(AssistantAlarmTimerControllerTest, - TimerNotificationHasExpectedPriority) { - ASSERT_FALSE(chromeos::assistant::features::IsTimersV2Enabled()); - - // Observe notifications. - ScopedNotificationModelObserver notification_model_observer; - - // Fire a timer. - FireTimer{kTimerId}; - - // Make assertions about the notification. - EXPECT_EQ(ExpectedNotification().WithClientId(kClientId).WithPriority( - AssistantNotificationPriority::kHigh), - notification_model_observer.last_notification()); -} - // Tests that a notification is added for a timer and has the expected priority // at various stages of its lifecycle. -// NOTE: This test is only applicable to timers v2. TEST_F(AssistantAlarmTimerControllerTest, - TimerNotificationHasExpectedPriorityV2) { - // Enable timers v2. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - chromeos::assistant::features::kAssistantTimersV2); - ASSERT_TRUE(chromeos::assistant::features::IsTimersV2Enabled()); - + TimerNotificationHasExpectedPriority) { // Observe notifications. ScopedNotificationModelObserver notification_model_observer; @@ -999,31 +717,8 @@ notification_model_observer.last_notification()); } -// Tests that a notification is added for a timer and is not pinned. -// NOTE: This test is only applicable to timers v1. -TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationIsNotPinned) { - ASSERT_FALSE(chromeos::assistant::features::IsTimersV2Enabled()); - - // Observe notifications. - ScopedNotificationModelObserver observer; - - // Fire a timer. - FireTimer{kTimerId}; - - // Make assertions about the notification. - EXPECT_EQ(ExpectedNotification().WithClientId(kClientId).WithIsPinned(false), - observer.last_notification()); -} - // Tests that a notification is added for a timer and is pinned. -// NOTE: This test is only applicable to timers v2. TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationIsPinned) { - // Enable timers v2. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - chromeos::assistant::features::kAssistantTimersV2); - ASSERT_TRUE(chromeos::assistant::features::IsTimersV2Enabled()); - // Observe notifications. ScopedNotificationModelObserver observer;
diff --git a/ash/assistant/assistant_interaction_controller_impl.cc b/ash/assistant/assistant_interaction_controller_impl.cc index d8e54ba..9ef07f085 100644 --- a/ash/assistant/assistant_interaction_controller_impl.cc +++ b/ash/assistant/assistant_interaction_controller_impl.cc
@@ -45,7 +45,6 @@ namespace { -using chromeos::assistant::features::IsTimersV2Enabled; using chromeos::assistant::features::IsWaitSchedulingEnabled; // Android.
diff --git a/ash/events/accessibility_event_rewriter_unittest.cc b/ash/events/accessibility_event_rewriter_unittest.cc index e063597..acfea7f 100644 --- a/ash/events/accessibility_event_rewriter_unittest.cc +++ b/ash/events/accessibility_event_rewriter_unittest.cc
@@ -165,6 +165,7 @@ bool IsSearchKeyAcceleratorReserved() const override { return false; } bool NotifyDeprecatedRightClickRewrite() override { return false; } + bool NotifyDeprecatedFKeyRewrite() override { return false; } bool NotifyDeprecatedAltBasedKeyRewrite(ui::KeyboardCode key_code) override { return false; }
diff --git a/ash/system/power/peripheral_battery_notifier_listener_integration_test.cc b/ash/system/power/peripheral_battery_notifier_listener_integration_test.cc index f620a5e..5c9c29b 100644 --- a/ash/system/power/peripheral_battery_notifier_listener_integration_test.cc +++ b/ash/system/power/peripheral_battery_notifier_listener_integration_test.cc
@@ -167,7 +167,6 @@ }; TEST_F(PeripheralBatteryNotifierListenerTest, Basic) { - // Level 50 at time 100, no low-battery notification. ClockAdvance(base::TimeDelta::FromSeconds(100)); SendBatteryUpdate(kTestBatteryPath, kTestDeviceName, 50);
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index 6b09dde..91a3810 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc
@@ -56,7 +56,7 @@ #include "ui/display/screen.h" #include "ui/display/test/display_manager_test_api.h" #include "ui/display/types/display_constants.h" -#include "ui/events/devices/device_data_manager_test_api.h" +#include "ui/events/devices/device_data_manager.h" #include "ui/events/devices/touchscreen_device.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" @@ -141,8 +141,7 @@ display::Display::SetInternalDisplayId(display::kInvalidDisplayId); // Tests can add devices, so reset the lists for future tests. - ui::DeviceDataManagerTestApi().SetTouchscreenDevices({}); - ui::DeviceDataManagerTestApi().SetKeyboardDevices({}); + ui::DeviceDataManager::GetInstance()->ResetDeviceListsForTest(); } // static
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 3d46760..268f7913 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -3569,6 +3569,7 @@ } bool IsSearchKeyAcceleratorReserved() const override { return true; } bool NotifyDeprecatedRightClickRewrite() override { return false; } + bool NotifyDeprecatedFKeyRewrite() override { return false; } bool NotifyDeprecatedAltBasedKeyRewrite(ui::KeyboardCode key_code) override { return false; }
diff --git a/base/BUILD.gn b/base/BUILD.gn index 90b6e67..9749c2d 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1164,16 +1164,12 @@ "mac/mac_util.mm", "mac/mach_logging.cc", "mac/mach_logging.h", - "mac/mach_o.cc", - "mac/mach_o.h", "mac/mach_port_rendezvous.cc", "mac/mach_port_rendezvous.h", "mac/objc_release_properties.h", "mac/objc_release_properties.mm", "mac/os_crash_dumps.cc", "mac/os_crash_dumps.h", - "mac/rosetta.h", - "mac/rosetta.mm", "mac/scoped_aedesc.h", "mac/scoped_authorizationref.h", "mac/scoped_authorizationref.mm", @@ -2783,15 +2779,6 @@ "test/data/serializer_test.json", "test/data/serializer_test_nowhitespace.json", ] - if (is_mac) { - sources += [ - "test/data/mac/arm64", - "test/data/mac/elf", - "test/data/mac/universal", - "test/data/mac/x86", - "test/data/mac/x86_64", - ] - } outputs = [ "{{bundle_resources_dir}}/" + "{{source_root_relative_dir}}/{{source_file_part}}" ] } @@ -3282,7 +3269,6 @@ "mac/dispatch_source_mach_unittest.cc", "mac/foundation_util_unittest.mm", "mac/mac_util_unittest.mm", - "mac/mach_o_unittest.cc", "mac/mach_port_rendezvous_unittest.cc", "mac/objc_release_properties_unittest.mm", "mac/scoped_mach_vm_unittest.cc", @@ -3291,7 +3277,6 @@ "mac/scoped_sending_event_unittest.mm", "message_loop/message_pump_mac_unittest.mm", "power_monitor/thermal_state_observer_mac_unittest.mm", - "process/launch_unittest_mac.cc", "process/memory_unittest_mac.h", "process/memory_unittest_mac.mm", "strings/sys_string_conversions_mac_unittest.mm", @@ -3864,6 +3849,7 @@ "android/java/src/org/chromium/base/annotations/VerifiesOnP.java", "android/java/src/org/chromium/base/annotations/VerifiesOnQ.java", "android/java/src/org/chromium/base/annotations/VerifiesOnR.java", + "android/java/src/org/chromium/base/annotations/VerifiesOnS.java", "android/java/src/org/chromium/base/compat/ApiHelperForM.java", "android/java/src/org/chromium/base/compat/ApiHelperForN.java", "android/java/src/org/chromium/base/compat/ApiHelperForO.java", @@ -3871,6 +3857,7 @@ "android/java/src/org/chromium/base/compat/ApiHelperForP.java", "android/java/src/org/chromium/base/compat/ApiHelperForQ.java", "android/java/src/org/chromium/base/compat/ApiHelperForR.java", + "android/java/src/org/chromium/base/compat/ApiHelperForS.java", "android/java/src/org/chromium/base/library_loader/LegacyLinker.java", "android/java/src/org/chromium/base/library_loader/LibraryLoader.java", "android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java",
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java index dafdce6..eebae13 100644 --- a/base/android/java/src/org/chromium/base/BuildInfo.java +++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -32,6 +32,10 @@ private static PackageInfo sBrowserPackageInfo; private static boolean sInitialized; + // TODO(crbug.com/1192402): Replace this with Build.VERSION_CODES.S in the code once chromium + // import Android S SDK. + public static final int ANDROID_S_API_SDK_INT = 31; + /** Not a member variable to avoid creating the instance early (it is set early in start up). */ private static String sFirebaseAppId = "";
diff --git a/base/android/java/src/org/chromium/base/annotations/VerifiesOnS.java b/base/android/java/src/org/chromium/base/annotations/VerifiesOnS.java new file mode 100644 index 0000000..1c1b079 --- /dev/null +++ b/base/android/java/src/org/chromium/base/annotations/VerifiesOnS.java
@@ -0,0 +1,21 @@ +// 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.base.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The annotated method or class verifies on S, but not below. + * + * The annotated method (or methods on the annotated class) are guaranteed to not be inlined by R8 + * on builds targeted below S. This prevents class verification errors (which results in a very slow + * retry-verification-at-runtime) from spreading into other classes on these lower versions. + */ +@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.CLASS) +public @interface VerifiesOnS {} \ No newline at end of file
diff --git a/base/android/java/src/org/chromium/base/compat/ApiHelperForS.java b/base/android/java/src/org/chromium/base/compat/ApiHelperForS.java new file mode 100644 index 0000000..32ae6d0 --- /dev/null +++ b/base/android/java/src/org/chromium/base/compat/ApiHelperForS.java
@@ -0,0 +1,41 @@ +// 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.base.compat; + +import android.annotation.TargetApi; +import android.content.ClipDescription; + +import org.chromium.base.BuildInfo; +import org.chromium.base.Log; +import org.chromium.base.annotations.VerifiesOnS; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Utility class to use new APIs that were added in S (API level 31). These need to exist in a + * separate class so that Android framework can successfully verify classes without + * encountering the new APIs. + */ +@VerifiesOnS +@TargetApi(BuildInfo.ANDROID_S_API_SDK_INT) +public final class ApiHelperForS { + private static final String TAG = "ApiHelperForS"; + + private ApiHelperForS() {} + + /** + * See {@link ClipDescription#isStyleText()}. + */ + public static boolean isStyleText(ClipDescription clipDescription) { + try { + Method isStyledTextMethod = ClipDescription.class.getDeclaredMethod("isStyledText"); + return (boolean) isStyledTextMethod.invoke(clipDescription); + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { + Log.e(TAG, "Failed to invoke ClipDescription#isStyledText() ", e); + return false; + } + } +} \ No newline at end of file
diff --git a/base/command_line.h b/base/command_line.h index 04c76df..a9f4dd2 100644 --- a/base/command_line.h +++ b/base/command_line.h
@@ -38,8 +38,8 @@ using StringType = std::string; #endif - using StringPieceType = base::BasicStringPiece<StringType>; using CharType = StringType::value_type; + using StringPieceType = base::BasicStringPiece<CharType>; using StringVector = std::vector<StringType>; using SwitchMap = std::map<std::string, StringType, std::less<>>;
diff --git a/base/files/file_path.h b/base/files/file_path.h index c87fe5a..b122de6 100644 --- a/base/files/file_path.h +++ b/base/files/file_path.h
@@ -161,8 +161,8 @@ typedef std::string StringType; #endif // OS_WIN - typedef BasicStringPiece<StringType> StringPieceType; typedef StringType::value_type CharType; + typedef BasicStringPiece<CharType> StringPieceType; // Null-terminated array of separators used to separate components in // hierarchical paths. Each character in this array is a valid separator,
diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm index 3e1b51a..7c7c3e8 100644 --- a/base/mac/mac_util.mm +++ b/base/mac/mac_util.mm
@@ -10,6 +10,8 @@ #include <errno.h> #include <stddef.h> #include <string.h> +#include <sys/sysctl.h> +#include <sys/types.h> #include <sys/utsname.h> #include <sys/xattr.h> @@ -18,7 +20,6 @@ #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" #include "base/mac/mac_logging.h" -#include "base/mac/rosetta.h" #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_ioobject.h" #include "base/mac/scoped_nsobject.h" @@ -405,6 +406,21 @@ } // namespace internal +namespace { + +#if defined(ARCH_CPU_X86_64) +// https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment#3616845 +bool ProcessIsTranslated() { + int ret = 0; + size_t size = sizeof(ret); + if (sysctlbyname("sysctl.proc_translated", &ret, &size, nullptr, 0) == -1) + return false; + return ret; +} +#endif // ARCH_CPU_X86_64 + +} // namespace + CPUType GetCPUType() { #if defined(ARCH_CPU_ARM64) return CPUType::kArm;
diff --git a/base/mac/mach_o.cc b/base/mac/mach_o.cc deleted file mode 100644 index 8d90e81..0000000 --- a/base/mac/mach_o.cc +++ /dev/null
@@ -1,150 +0,0 @@ -// Copyright 2020 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 "base/mac/mach_o.h" - -#include <mach/machine.h> - -#include <vector> - -#include "base/check.h" -#include "base/check_op.h" -#include "base/containers/span.h" -#include "base/files/file.h" -#include "base/sys_byteorder.h" - -namespace base { - -namespace { - -// ByteSwap is only implemented for unsigned types, and cpu_type_t is a signed -// type. -cpu_type_t ByteSwapCPUType(const cpu_type_t cputype) { - return static_cast<cpu_type_t>( - ByteSwap(static_cast<std::make_unsigned<cpu_type_t>::type>(cputype))); -} - -MachOArchitectures CPUTypeToBit(const cpu_type_t cputype) { - switch (cputype) { - case CPU_TYPE_X86_64: - return MachOArchitectures::kX86_64; - case CPU_TYPE_ARM64: - return MachOArchitectures::kARM64; - default: - return MachOArchitectures::kUnknownArchitecture; - } -} - -template <typename FatArchType> -MachOArchitectures GetFatMachOArchitectures(File& file, - const uint32_t nfat_arch, - const bool swap) { - MachOArchitectures result = static_cast<MachOArchitectures>(0); - - std::vector<FatArchType> archs(nfat_arch); - if (!file.ReadAtCurrentPosAndCheck( - as_writable_bytes(make_span(archs.data(), archs.size())))) { - return MachOArchitectures::kInvalidFormat; - } - - for (const FatArchType& arch : archs) { - result |= CPUTypeToBit(swap ? ByteSwapCPUType(arch.cputype) : arch.cputype); - } - - DCHECK_NE(result, static_cast<MachOArchitectures>(0)); - - return result; -} - -} // namespace - -MachOArchitectures GetMachOArchitectures(const FilePath& path) { - File file(path, File::FLAG_OPEN | File::FLAG_READ); - if (!file.IsValid()) { - return MachOArchitectures::kFileError; - } - - union { - uint32_t magic; - - // In a 64-bit file, the header will be a mach_header_64 instead of a - // mach_header, but the only difference between the two is that the latter - // ends with a 4-byte padding field. This function does not consider - // anything beyond the header, so mach_header will suffice in place of - // mach_header_64. - mach_header mach; - - fat_header fat; - } header; - if (!file.ReadAtCurrentPosAndCheck( - as_writable_bytes(make_span(&header.magic, 1)))) { - return MachOArchitectures::kInvalidFormat; - } - - switch (header.magic) { - case MH_MAGIC: - case MH_MAGIC_64: - case MH_CIGAM: - case MH_CIGAM_64: { - const bool is_64 = - header.magic == MH_MAGIC_64 || header.magic == MH_CIGAM_64; - const bool swap = header.magic == MH_CIGAM || header.magic == MH_CIGAM_64; - - if (!file.ReadAtCurrentPosAndCheck( - as_writable_bytes(make_span(&header.mach, 1)) - .subspan(sizeof(header.magic)))) { - return MachOArchitectures::kInvalidFormat; - } - - if (swap) { - header.mach.magic = ByteSwap(header.mach.magic); - header.mach.cputype = ByteSwapCPUType(header.mach.cputype); - } - - DCHECK(header.mach.magic == MH_MAGIC || header.mach.magic == MH_MAGIC_64); - DCHECK_EQ(header.mach.magic == MH_MAGIC_64, is_64); - - return CPUTypeToBit(header.mach.cputype); - } - - case FAT_MAGIC: - case FAT_MAGIC_64: - case FAT_CIGAM: - case FAT_CIGAM_64: { - const bool is_64 = - header.magic == FAT_MAGIC_64 || header.magic == FAT_CIGAM_64; - const bool swap = - header.magic == FAT_CIGAM || header.magic == FAT_CIGAM_64; - - if (!file.ReadAtCurrentPosAndCheck( - as_writable_bytes(make_span(&header.fat, 1)) - .subspan(sizeof(header.magic)))) { - return MachOArchitectures::kInvalidFormat; - } - - if (swap) { - header.fat.magic = ByteSwap(header.fat.magic); - header.fat.nfat_arch = ByteSwap(header.fat.nfat_arch); - } - - DCHECK(header.fat.magic == FAT_MAGIC || header.fat.magic == FAT_MAGIC_64); - DCHECK_EQ(header.fat.magic == FAT_MAGIC_64, is_64); - - if (header.fat.nfat_arch == 0) { - return MachOArchitectures::kInvalidFormat; - } - - return is_64 ? GetFatMachOArchitectures<fat_arch_64>( - file, header.fat.nfat_arch, swap) - : GetFatMachOArchitectures<fat_arch>( - file, header.fat.nfat_arch, swap); - } - - default: { - return MachOArchitectures::kInvalidFormat; - } - } -} - -} // namespace base
diff --git a/base/mac/mach_o.h b/base/mac/mach_o.h deleted file mode 100644 index e545ed01..0000000 --- a/base/mac/mach_o.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2020 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 BASE_MAC_MACH_O_H_ -#define BASE_MAC_MACH_O_H_ - -#include <mach-o/fat.h> -#include <mach-o/loader.h> -#include <stdint.h> - -#include <type_traits> - -#include "base/base_export.h" -#include "base/files/file_path.h" - -namespace base { - -// The return value of MachOArchitectures. -enum class MachOArchitectures : uint32_t { - // Corresponds to cpu_type_t CPU_TYPE_X86_64. - kX86_64 = 1 << 0, - - // Corresponds to cpu_type_t CPU_TYPE_ARM64. - kARM64 = 1 << 1, - - // A Mach-O file with an architecture other than one of those listed above. - kUnknownArchitecture = 1 << 29, - - // Not a Mach-O file. This bit may only appear alone. - kInvalidFormat = 1 << 30, - - // Not a file at all. This bit may only appear alone. - kFileError = 1 << 31, -}; - -// MachOArchitectures is an enum class for better namespacing, but it’s treated -// as a bitfield, so define a few operators to make it easier to work with. - -inline constexpr MachOArchitectures operator&(MachOArchitectures a, - MachOArchitectures b) { - using UnderlyingType = std::underlying_type<MachOArchitectures>::type; - return static_cast<MachOArchitectures>(static_cast<UnderlyingType>(a) & - static_cast<UnderlyingType>(b)); -} - -inline constexpr MachOArchitectures operator|(MachOArchitectures a, - MachOArchitectures b) { - using UnderlyingType = std::underlying_type<MachOArchitectures>::type; - return static_cast<MachOArchitectures>(static_cast<UnderlyingType>(a) | - static_cast<UnderlyingType>(b)); -} - -inline constexpr MachOArchitectures operator|=(MachOArchitectures& a, - MachOArchitectures b) { - a = a | b; - return a; -} - -// Determines the CPU architecture of a Mach-O file, or the CPU architectures of -// a fat file. -// -// This only considers the mach_header[_64]::cputype field of (thin) Mach-O -// files, and the fat_arch[_64]::cputype fields of fat files. For a fat file, -// more than one bit may be set in the return value. -BASE_EXPORT MachOArchitectures GetMachOArchitectures(const FilePath& path); - -} // namespace base - -#endif // BASE_MAC_MACH_O_H_
diff --git a/base/mac/mach_o_unittest.cc b/base/mac/mach_o_unittest.cc deleted file mode 100644 index 1703b35..0000000 --- a/base/mac/mach_o_unittest.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2020 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 "base/mac/mach_o.h" - -#include "base/base_paths.h" -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { -namespace { - -TEST(MachO, GetMachOArchitectures) { - FilePath exe_path; - ASSERT_TRUE(PathService::Get(FILE_EXE, &exe_path)); -#if defined(ARCH_CPU_X86_64) - constexpr MachOArchitectures kSelfArchitecture = MachOArchitectures::kX86_64; -#elif defined(ARCH_CPU_ARM64) - constexpr MachOArchitectures kSelfArchitecture = MachOArchitectures::kARM64; -#endif - EXPECT_EQ(GetMachOArchitectures(exe_path) & kSelfArchitecture, - kSelfArchitecture); - - FilePath data_dir; - ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir)); - data_dir = data_dir.AppendASCII("mac"); - - EXPECT_EQ(GetMachOArchitectures(data_dir.AppendASCII("x86_64")), - MachOArchitectures::kX86_64); - - EXPECT_EQ(GetMachOArchitectures(data_dir.AppendASCII("arm64")), - MachOArchitectures::kARM64); - - EXPECT_EQ(GetMachOArchitectures(data_dir.AppendASCII("universal")), - MachOArchitectures::kX86_64 | MachOArchitectures::kARM64); - - EXPECT_EQ(GetMachOArchitectures(data_dir.AppendASCII("x86")), - MachOArchitectures::kUnknownArchitecture); - - EXPECT_EQ(GetMachOArchitectures(data_dir.AppendASCII("elf")), - MachOArchitectures::kInvalidFormat); - - EXPECT_EQ(GetMachOArchitectures(data_dir.AppendASCII("enoent")), - MachOArchitectures::kFileError); -} - -} // namespace -} // namespace base
diff --git a/base/mac/rosetta.h b/base/mac/rosetta.h deleted file mode 100644 index 13cf702..0000000 --- a/base/mac/rosetta.h +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2020 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 BASE_MAC_ROSETTA_H_ -#define BASE_MAC_ROSETTA_H_ - -#include <string> -#include <vector> - -#include "base/base_export.h" -#include "base/callback.h" -#include "build/build_config.h" - -namespace base { - -class FilePath; - -namespace mac { - -#if defined(ARCH_CPU_X86_64) - -// Returns true if the current process is being translated by Rosetta. -bool ProcessIsTranslated(); - -#endif // ARCH_CPU_X86_64 - -#if defined(ARCH_CPU_ARM64) - -// Returns true if Rosetta is installed and available to translate x86_64 code. -BASE_EXPORT bool IsRosettaInstalled(); - -// Prompt the user to allow for the installation of Rosetta. `callback` is -// called with the result of the Rosetta installation. The UI is presented to -// the user in a dialog with the `title_text` and `body_text`. Its thread-safety -// is not known; call it from the main thread and the callback will happen on -// the main thread as well. -enum class RosettaInstallationResult { - kFailedToAccessSPI, - kAlreadyInstalled, - kInstallationFailure, - kInstallationSuccess, -}; -BASE_EXPORT void RequestRosettaInstallation( - const std::u16string& title_text, - const std::u16string& body_text, - OnceCallback<void(RosettaInstallationResult)> callback); - -#endif // ARCH_CPU_ARM64 - -// Requests an ahead-of-time translation of the binaries with paths given in -// `binaries`. Returns the success value (true == success, false == failure) -// indicated by the underlying call. -// -// Observed behavior about Rosetta AOT translation: -// - If a binary was already translated, it will not be translated again. -// - The call blocks and waits for the completion of the translation. Do not -// call this on the main thread. -BASE_EXPORT bool RequestRosettaAheadOfTimeTranslation( - const std::vector<FilePath>& binaries); - -} // namespace mac -} // namespace base - -#endif // BASE_MAC_ROSETTA_H_
diff --git a/base/mac/rosetta.mm b/base/mac/rosetta.mm deleted file mode 100644 index 65d9a657..0000000 --- a/base/mac/rosetta.mm +++ /dev/null
@@ -1,200 +0,0 @@ -// Copyright 2020 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 "base/mac/rosetta.h" - -#include <AppKit/AppKit.h> -#include <CoreFoundation/CoreFoundation.h> -#include <dlfcn.h> -#include <mach/machine.h> -#include <string.h> -#include <sys/sysctl.h> -#include <sys/types.h> - -#include <utility> - -#include "base/check.h" -#include "base/files/file_path.h" -#include "base/mac/scoped_nsobject.h" -#include "base/mac/sdk_forward_declarations.h" -#include "base/no_destructor.h" -#include "base/strings/sys_string_conversions.h" -#include "base/threading/scoped_blocking_call.h" -#include "build/build_config.h" - -namespace base { -namespace mac { - -#if defined(ARCH_CPU_X86_64) - -// https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment#3616845 -bool ProcessIsTranslated() { - int ret = 0; - size_t size = sizeof(ret); - if (sysctlbyname("sysctl.proc_translated", &ret, &size, nullptr, 0) == -1) - return false; - return ret; -} - -#endif // ARCH_CPU_X86_64 - -#if defined(ARCH_CPU_ARM64) - -bool IsRosettaInstalled() { - if (@available(macOS 11.0, *)) { - return CFBundleIsArchitectureLoadable(CPU_TYPE_X86_64); - } else { - // Arm Macs require at least 11.0 to run, so this branch will never be - // taken. - NOTREACHED(); - return false; - } -} - -void RequestRosettaInstallation( - const std::u16string& title_text, - const std::u16string& body_text, - OnceCallback<void(RosettaInstallationResult)> callback) { - DCHECK([NSThread isMainThread]); - - if (IsRosettaInstalled()) { - std::move(callback).Run(RosettaInstallationResult::kAlreadyInstalled); - return; - } - - static NSObject* current_rosetta_installation = nil; - if (current_rosetta_installation) { - if ([current_rosetta_installation - respondsToSelector:@selector(windowController)]) { - NSWindowController* windowController = [current_rosetta_installation - performSelector:@selector(windowController)]; - if (windowController && - [windowController isKindOfClass:[NSWindowController class]]) { - [windowController showWindow:nil]; - } - } - return; - } - - @autoreleasepool { - static const NoDestructor<scoped_nsobject<NSBundle>> bundle([]() { - scoped_nsobject<NSBundle> bundle( - [[NSBundle alloc] initWithPath:@"/System/Library/PrivateFrameworks/" - @"OAHSoftwareUpdate.framework"]); - if (![bundle load]) - return scoped_nsobject<NSBundle>(); - - return bundle; - }()); - if (!bundle.get()) { - std::move(callback).Run(RosettaInstallationResult::kFailedToAccessSPI); - return; - } - - // The method being called is: - // - // - (void)[OAHSoftwareUpdateController - // startUpdateWithOptions:(NSDictionary*)options - // withHostWindow:(NSWindow*)window - // completion:(void (^)(BOOL, NSError*))block] - SEL selector = @selector(startUpdateWithOptions:withHostWindow:completion:); - - scoped_nsobject<NSObject> controller( - [[NSClassFromString(@"OAHSoftwareUpdateController") alloc] init]); - NSMethodSignature* signature = - [controller methodSignatureForSelector:selector]; - if (!signature) { - std::move(callback).Run(RosettaInstallationResult::kFailedToAccessSPI); - return; - } - if (strcmp(signature.methodReturnType, "v") != 0 || - signature.numberOfArguments != 5 || - strcmp([signature getArgumentTypeAtIndex:0], "@") != 0 || - strcmp([signature getArgumentTypeAtIndex:1], ":") != 0 || - strcmp([signature getArgumentTypeAtIndex:2], "@") != 0 || - strcmp([signature getArgumentTypeAtIndex:3], "@") != 0 || - strcmp([signature getArgumentTypeAtIndex:4], "@?") != 0) { - std::move(callback).Run(RosettaInstallationResult::kFailedToAccessSPI); - return; - } - - NSInvocation* invocation = - [NSInvocation invocationWithMethodSignature:signature]; - - current_rosetta_installation = [controller.get() retain]; - invocation.target = current_rosetta_installation; - invocation.selector = selector; - - NSDictionary* options = @{ - @"TitleText" : SysUTF16ToNSString(title_text), - @"BodyText" : SysUTF16ToNSString(body_text) - }; - [invocation setArgument:&options atIndex:2]; - - NSWindow* window = nil; - [invocation setArgument:&window atIndex:3]; - - __block OnceCallback<void(RosettaInstallationResult)> block_callback = - std::move(callback); - auto completion = ^(BOOL success, NSError* error) { - // There _should_ be a valid callback and current_rosetta_installation - // here. However, crashes indicate that sometimes - // OAHSoftwareUpdateController performs a double-callback of the block. - // Therefore, be paranoid. - if (current_rosetta_installation) { - [current_rosetta_installation release]; - current_rosetta_installation = nil; - } - if (block_callback) { - std::move(block_callback) - .Run(success ? RosettaInstallationResult::kInstallationSuccess - : RosettaInstallationResult::kInstallationFailure); - } - }; - - [invocation setArgument:&completion atIndex:4]; - - [invocation invoke]; - } -} - -#endif // ARCH_CPU_ARM64 - -bool RequestRosettaAheadOfTimeTranslation( - const std::vector<FilePath>& binaries) { -#if defined(ARCH_CPU_X86_64) - if (!ProcessIsTranslated()) - return false; -#endif // ARCH_CPU_X86_64 - - // It's unclear if this is a BOOL or Boolean or bool. It's returning 0 or 1 - // in w0, so just grab the result as an int and convert here. - // int rosetta_translate_binaries(const char*[] paths, int npaths) - using rosetta_translate_binaries_t = int (*)(const char*[], int); - static auto rosetta_translate_binaries = []() { - void* librosetta = - dlopen("/usr/lib/libRosetta.dylib", RTLD_LAZY | RTLD_LOCAL); - if (!librosetta) - return static_cast<rosetta_translate_binaries_t>(nullptr); - return reinterpret_cast<rosetta_translate_binaries_t>( - dlsym(librosetta, "rosetta_translate_binaries")); - }(); - if (!rosetta_translate_binaries) - return false; - - std::vector<std::string> paths; - std::vector<const char*> path_strs; - paths.reserve(binaries.size()); - path_strs.reserve(paths.size()); - for (const auto& binary : binaries) { - paths.push_back(FilePath::GetHFSDecomposedForm(binary.value())); - path_strs.push_back(paths.back().c_str()); - } - - ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK); - return rosetta_translate_binaries(path_strs.data(), path_strs.size()); -} - -} // namespace mac -} // namespace base
diff --git a/base/process/launch.h b/base/process/launch.h index 2d7425f..16bef70 100644 --- a/base/process/launch.h +++ b/base/process/launch.h
@@ -227,13 +227,6 @@ // Apply a process scheduler policy to enable mitigations against CPU side- // channel attacks. bool enable_cpu_security_mitigations = false; - -#if defined(ARCH_CPU_ARM64) - // If true, the child process will be launched as x86_64 code under Rosetta - // translation. The executable being launched must contain x86_64 code, either - // as a thin Mach-O file targeting x86_64, or a fat file with an x86_64 slice. - bool launch_x86_64 = false; -#endif // ARCH_CPU_ARM64 #endif // OS_MAC #if defined(OS_FUCHSIA)
diff --git a/base/process/launch_mac.cc b/base/process/launch_mac.cc index 05ad864..a8713e1 100644 --- a/base/process/launch_mac.cc +++ b/base/process/launch_mac.cc
@@ -17,7 +17,6 @@ #include "base/logging.h" #include "base/posix/eintr_wrapper.h" #include "base/process/environment_internal.h" -#include "base/stl_util.h" #include "base/threading/scoped_blocking_call.h" #include "base/threading/thread_restrictions.h" #include "base/trace_event/base_tracing.h" @@ -256,14 +255,6 @@ ? options.real_path.value().c_str() : argv_cstr[0]; -#if defined(ARCH_CPU_ARM64) - if (options.launch_x86_64) { - cpu_type_t cpu_types[] = {CPU_TYPE_X86_64}; - DPSXCHECK(posix_spawnattr_setbinpref_np(attr.get(), base::size(cpu_types), - cpu_types, nullptr)); - } -#endif // ARCH_CPU_ARM64 - if (__builtin_available(macOS 11.0, *)) { if (options.enable_cpu_security_mitigations) { DPSXCHECK(posix_spawnattr_set_csm_np(attr.get(), POSIX_SPAWN_NP_CSM_ALL));
diff --git a/base/process/launch_unittest_mac.cc b/base/process/launch_unittest_mac.cc deleted file mode 100644 index c06043f..0000000 --- a/base/process/launch_unittest_mac.cc +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2020 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 "base/process/launch.h" - -#include <errno.h> -#include <stdio.h> -#include <unistd.h> - -#include <string> -#include <utility> -#include <vector> - -#include "base/base_paths.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/macros.h" -#include "base/path_service.h" -#include "base/posix/safe_strerror.h" -#include "base/process/process.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { -namespace { - -void LaunchMacTest(const FilePath& exe_path, - LaunchOptions options, - const std::string& expected_output) { - ScopedFD pipe_read_fd; - ScopedFD pipe_write_fd; - { - int pipe_fds[2]; - ASSERT_EQ(pipe(pipe_fds), 0) << safe_strerror(errno); - pipe_read_fd.reset(pipe_fds[0]); - pipe_write_fd.reset(pipe_fds[1]); - } - - ScopedFILE pipe_read_file(fdopen(pipe_read_fd.get(), "r")); - ASSERT_TRUE(pipe_read_file) << "fdopen: " << safe_strerror(errno); - ignore_result(pipe_read_fd.release()); - - std::vector<std::string> argv(1, exe_path.value()); - options.fds_to_remap.emplace_back(pipe_write_fd.get(), STDOUT_FILENO); - Process process = LaunchProcess(argv, options); - ASSERT_TRUE(process.IsValid()); - pipe_write_fd.reset(); - - // Not ASSERT_TRUE because it's important to reach process.WaitForExit. - std::string output; - EXPECT_TRUE(ReadStreamToString(pipe_read_file.get(), &output)); - - int exit_code; - ASSERT_TRUE(process.WaitForExit(&exit_code)); - EXPECT_EQ(exit_code, 0); - - EXPECT_EQ(output, expected_output); -} - -#if defined(ARCH_CPU_ARM64) -// Bulk-disabled on arm64 for bot stabilization: https://crbug.com/1154345 -#define MAYBE_LaunchMac DISABLED_LaunchMac -#else -#define MAYBE_LaunchMac LaunchMac -#endif -TEST(Process, MAYBE_LaunchMac) { - FilePath data_dir; - ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir)); - data_dir = data_dir.AppendASCII("mac"); - -#if defined(ARCH_CPU_X86_64) - static constexpr char kArchitecture[] = "x86_64"; -#elif defined(ARCH_CPU_ARM64) - static constexpr char kArchitecture[] = "arm64"; -#endif - - LaunchOptions options; - LaunchMacTest(data_dir.AppendASCII(kArchitecture), options, - std::string(kArchitecture) + "\n"); - -#if defined(ARCH_CPU_ARM64) - static constexpr char kUniversal[] = "universal"; - - LaunchMacTest(data_dir.AppendASCII(kUniversal), options, - std::string(kArchitecture) + "\n"); - - static constexpr char kX86_64[] = "x86_64"; - - LaunchMacTest(data_dir.AppendASCII(kX86_64), options, - std::string(kX86_64) + "\n"); - - options.launch_x86_64 = true; - LaunchMacTest(data_dir.AppendASCII(kUniversal), options, - std::string(kX86_64) + "\n"); - - LaunchMacTest(data_dir.AppendASCII(kX86_64), options, - std::string(kX86_64) + "\n"); -#endif // ARCH_CPU_ARM64 -} - -} // namespace -} // namespace base
diff --git a/base/strings/string_number_conversions_internal.h b/base/strings/string_number_conversions_internal.h index cb99849..66ff22c 100644 --- a/base/strings/string_number_conversions_internal.h +++ b/base/strings/string_number_conversions_internal.h
@@ -179,8 +179,8 @@ }; }; -template <typename Number, int kBase, typename Str> -auto StringToNumber(BasicStringPiece<Str> input) { +template <typename Number, int kBase, typename CharT> +auto StringToNumber(BasicStringPiece<CharT> input) { using Parser = StringToNumberParser<Number, kBase>; using Result = typename Parser::Result; @@ -212,15 +212,15 @@ return result; } -template <typename STR, typename VALUE> -bool StringToIntImpl(BasicStringPiece<STR> input, VALUE& output) { +template <typename CharT, typename VALUE> +bool StringToIntImpl(BasicStringPiece<CharT> input, VALUE& output) { auto result = StringToNumber<VALUE, 10>(input); output = result.value; return result.valid; } -template <typename STR, typename VALUE> -bool HexStringToIntImpl(BasicStringPiece<STR> input, VALUE& output) { +template <typename CharT, typename VALUE> +bool HexStringToIntImpl(BasicStringPiece<CharT> input, VALUE& output) { auto result = StringToNumber<VALUE, 16>(input); output = result.value; return result.valid;
diff --git a/base/strings/string_piece.cc b/base/strings/string_piece.cc index e9d6f683..cdceb88 100644 --- a/base/strings/string_piece.cc +++ b/base/strings/string_piece.cc
@@ -37,9 +37,9 @@ // MSVC doesn't like complex extern templates and DLLs. #if !defined(COMPILER_MSVC) -template class BasicStringPiece<std::string>; -template class BasicStringPiece<std::u16string>; -template class BasicStringPiece<std::wstring>; +template class BasicStringPiece<char>; +template class BasicStringPiece<char16_t>; +template class BasicStringPiece<wchar_t>; #endif std::ostream& operator<<(std::ostream& o, StringPiece piece) { @@ -57,16 +57,18 @@ namespace internal { -template <typename STR> -size_t findT(BasicStringPiece<STR> self, BasicStringPiece<STR> s, size_t pos) { +template <typename CharT> +size_t findT(BasicStringPiece<CharT> self, + BasicStringPiece<CharT> s, + size_t pos) { if (pos > self.size()) - return BasicStringPiece<STR>::npos; + return BasicStringPiece<CharT>::npos; - typename BasicStringPiece<STR>::const_iterator result = + typename BasicStringPiece<CharT>::const_iterator result = std::search(self.begin() + pos, self.end(), s.begin(), s.end()); const size_t xpos = static_cast<size_t>(result - self.begin()); - return xpos + s.size() <= self.size() ? xpos : BasicStringPiece<STR>::npos; + return xpos + s.size() <= self.size() ? xpos : BasicStringPiece<CharT>::npos; } size_t find(StringPiece self, StringPiece s, size_t pos) { @@ -77,20 +79,22 @@ return findT(self, s, pos); } -template <typename STR> -size_t rfindT(BasicStringPiece<STR> self, BasicStringPiece<STR> s, size_t pos) { +template <typename CharT> +size_t rfindT(BasicStringPiece<CharT> self, + BasicStringPiece<CharT> s, + size_t pos) { if (self.size() < s.size()) - return BasicStringPiece<STR>::npos; + return BasicStringPiece<CharT>::npos; if (s.empty()) return std::min(self.size(), pos); - typename BasicStringPiece<STR>::const_iterator last = + typename BasicStringPiece<CharT>::const_iterator last = self.begin() + std::min(self.size() - s.size(), pos) + s.size(); - typename BasicStringPiece<STR>::const_iterator result = + typename BasicStringPiece<CharT>::const_iterator result = std::find_end(self.begin(), last, s.begin(), s.end()); - return result != last ? - static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos; + return result != last ? static_cast<size_t>(result - self.begin()) + : BasicStringPiece<CharT>::npos; } size_t rfind(StringPiece self, StringPiece s, size_t pos) { @@ -121,17 +125,17 @@ } // Generic brute force version. -template <typename STR> -size_t find_first_ofT(BasicStringPiece<STR> self, - BasicStringPiece<STR> s, +template <typename CharT> +size_t find_first_ofT(BasicStringPiece<CharT> self, + BasicStringPiece<CharT> s, size_t pos) { // Use the faster std::find() if searching for a single character. - typename BasicStringPiece<STR>::const_iterator found = + typename BasicStringPiece<CharT>::const_iterator found = s.size() == 1 ? std::find(self.begin() + pos, self.end(), s[0]) : std::find_first_of(self.begin() + pos, self.end(), s.begin(), s.end()); if (found == self.end()) - return BasicStringPiece<STR>::npos; + return BasicStringPiece<CharT>::npos; return found - self.begin(); } @@ -162,12 +166,12 @@ } // Generic brute-force version. -template <typename STR> -size_t find_first_not_ofT(BasicStringPiece<STR> self, - BasicStringPiece<STR> s, +template <typename CharT> +size_t find_first_not_ofT(BasicStringPiece<CharT> self, + BasicStringPiece<CharT> s, size_t pos) { if (self.size() == 0) - return BasicStringPiece<STR>::npos; + return BasicStringPiece<CharT>::npos; for (size_t self_i = pos; self_i < self.size(); ++self_i) { bool found = false; @@ -180,7 +184,7 @@ if (!found) return self_i; } - return BasicStringPiece<STR>::npos; + return BasicStringPiece<CharT>::npos; } size_t find_first_not_of(StringPiece16 self, StringPiece16 s, size_t pos) { @@ -208,12 +212,12 @@ } // Generic brute-force version. -template <typename STR> -size_t find_last_ofT(BasicStringPiece<STR> self, - BasicStringPiece<STR> s, +template <typename CharT> +size_t find_last_ofT(BasicStringPiece<CharT> self, + BasicStringPiece<CharT> s, size_t pos) { if (self.size() == 0) - return BasicStringPiece<STR>::npos; + return BasicStringPiece<CharT>::npos; for (size_t self_i = std::min(pos, self.size() - 1); ; --self_i) { @@ -224,7 +228,7 @@ if (self_i == 0) break; } - return BasicStringPiece<STR>::npos; + return BasicStringPiece<CharT>::npos; } size_t find_last_of(StringPiece16 self, StringPiece16 s, size_t pos) { @@ -256,9 +260,9 @@ } // Generic brute-force version. -template <typename STR> -size_t find_last_not_ofT(BasicStringPiece<STR> self, - BasicStringPiece<STR> s, +template <typename CharT> +size_t find_last_not_ofT(BasicStringPiece<CharT> self, + BasicStringPiece<CharT> s, size_t pos) { if (self.size() == 0) return StringPiece::npos; @@ -276,7 +280,7 @@ if (self_i == 0) break; } - return BasicStringPiece<STR>::npos; + return BasicStringPiece<CharT>::npos; } size_t find_last_not_of(StringPiece16 self, StringPiece16 s, size_t pos) {
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h index 4923e979..f4f37ad5 100644 --- a/base/strings/string_piece.h +++ b/base/strings/string_piece.h
@@ -95,20 +95,18 @@ // Defines the types, methods, operators, and data members common to both // StringPiece and StringPiece16. -// -// This is templatized by string class type rather than character type, so -// BasicStringPiece<std::string> or BasicStringPiece<std::u16string>. -template <typename STRING_TYPE> class BasicStringPiece { +template <typename CharT> +class BasicStringPiece { public: // Standard STL container boilerplate. typedef size_t size_type; - typedef typename STRING_TYPE::traits_type traits_type; - typedef typename STRING_TYPE::value_type value_type; - typedef const value_type* pointer; - typedef const value_type& reference; - typedef const value_type& const_reference; + typedef std::char_traits<CharT> traits_type; + typedef CharT value_type; + typedef const CharT* pointer; + typedef const CharT& reference; + typedef const CharT& const_reference; typedef ptrdiff_t difference_type; - typedef const value_type* const_iterator; + typedef const CharT* const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; static const size_type npos; @@ -120,10 +118,10 @@ constexpr BasicStringPiece() : ptr_(nullptr), length_(0) {} // TODO(crbug.com/1049498): Construction from nullptr is not allowed for // std::basic_string_view, so remove the special handling for it. - // Note: This doesn't just use STRING_TYPE::traits_type::length(), since that + // Note: This doesn't just use traits_type::length(), since that // isn't constexpr until C++17. - constexpr BasicStringPiece(const value_type* str) - : ptr_(str), length_(!str ? 0 : CharTraits<value_type>::length(str)) {} + constexpr BasicStringPiece(const CharT* str) + : ptr_(str), length_(!str ? 0 : CharTraits<CharT>::length(str)) {} // Explicitly disallow construction from nullptr. Note that this does not // catch construction from runtime strings that might be null. // Note: The following is just a more elaborate way of spelling @@ -137,31 +135,31 @@ "StringPiece does not support construction from nullptr, use " "the default constructor instead."); } - BasicStringPiece(const STRING_TYPE& str) + BasicStringPiece(const std::basic_string<CharT>& str) : ptr_(str.data()), length_(str.size()) {} - constexpr BasicStringPiece(const value_type* offset, size_type len) + constexpr BasicStringPiece(const CharT* offset, size_type len) : ptr_(offset), length_(len) {} // data() may return a pointer to a buffer with embedded NULs, and the // returned buffer may or may not be null terminated. Therefore it is // typically a mistake to pass data() to a routine that expects a NUL // terminated string. - constexpr const value_type* data() const { return ptr_; } + constexpr const CharT* data() const { return ptr_; } constexpr size_type size() const noexcept { return length_; } constexpr size_type length() const noexcept { return length_; } constexpr bool empty() const noexcept { return length_ == 0; } - constexpr value_type operator[](size_type i) const { + constexpr CharT operator[](size_type i) const { CHECK(i < length_); return ptr_[i]; } - constexpr value_type front() const { + constexpr CharT front() const { CHECK_NE(0UL, length_); return ptr_[0]; } - constexpr value_type back() const { + constexpr CharT back() const { CHECK_NE(0UL, length_); return ptr_[length_ - 1]; } @@ -178,16 +176,16 @@ } // This is the style of conversion preferred by std::string_view in C++17. - explicit operator STRING_TYPE() const { - return empty() ? STRING_TYPE() : STRING_TYPE(data(), size()); + explicit operator std::basic_string<CharT>() const { + return std::basic_string<CharT>(data(), size()); } - // Deprecated, use operator STRING_TYPE() instead. - // TODO(crbug.com/1049498): Remove for all STRING_TYPEs. - template <typename StrT = STRING_TYPE, - typename = std::enable_if_t<std::is_same<StrT, std::string>::value>> - STRING_TYPE as_string() const { - return STRING_TYPE(*this); + // Deprecated, use operator std::basic_string<CharT>() instead. + // TODO(crbug.com/1049498): Remove for all CharTs. + template <typename ValueT = CharT, + typename = std::enable_if_t<std::is_same<ValueT, char>::value>> + std::basic_string<CharT> as_string() const { + return std::basic_string<CharT>(*this); } constexpr const_iterator begin() const noexcept { return ptr_; } @@ -203,9 +201,7 @@ size_type capacity() const { return length_; } // String operations, see https://wg21.link/string.view.ops. - constexpr size_type copy(value_type* s, - size_type n, - size_type pos = 0) const { + constexpr size_type copy(CharT* s, size_type n, size_type pos = 0) const { CHECK_LE(pos, size()); size_type rlen = std::min(n, size() - pos); traits_type::copy(s, data() + pos, rlen); @@ -220,7 +216,7 @@ constexpr int compare(BasicStringPiece str) const noexcept { size_type rlen = std::min(size(), str.size()); - int result = CharTraits<value_type>::compare(data(), str.data(), rlen); + int result = CharTraits<CharT>::compare(data(), str.data(), rlen); if (result == 0) result = size() == str.size() ? 0 : (size() < str.size() ? -1 : 1); return result; @@ -240,17 +236,17 @@ return substr(pos1, n1).compare(str.substr(pos2, n2)); } - constexpr int compare(const value_type* s) const { + constexpr int compare(const CharT* s) const { return compare(BasicStringPiece(s)); } - constexpr int compare(size_type pos, size_type n, const value_type* s) const { + constexpr int compare(size_type pos, size_type n, const CharT* s) const { return substr(pos, n).compare(BasicStringPiece(s)); } constexpr int compare(size_type pos, size_type n1, - const value_type* s, + const CharT* s, size_type n2) const { return substr(pos, n1).compare(BasicStringPiece(s, n2)); } @@ -263,22 +259,20 @@ return internal::find(*this, s, pos); } - constexpr size_type find(value_type c, size_type pos = 0) const noexcept { + constexpr size_type find(CharT c, size_type pos = 0) const noexcept { if (pos >= size()) return npos; - const value_type* result = - base::CharTraits<value_type>::find(data() + pos, size() - pos, c); + const CharT* result = + base::CharTraits<CharT>::find(data() + pos, size() - pos, c); return result ? static_cast<size_type>(result - data()) : npos; } - constexpr size_type find(const value_type* s, - size_type pos, - size_type n) const { + constexpr size_type find(const CharT* s, size_type pos, size_type n) const { return find(BasicStringPiece(s, n), pos); } - constexpr size_type find(const value_type* s, size_type pos = 0) const { + constexpr size_type find(const CharT* s, size_type pos = 0) const { return find(BasicStringPiece(s), pos); } @@ -288,7 +282,7 @@ return internal::rfind(*this, s, pos); } - constexpr size_type rfind(value_type c, size_type pos = npos) const noexcept { + constexpr size_type rfind(CharT c, size_type pos = npos) const noexcept { if (empty()) return npos; @@ -302,13 +296,11 @@ return npos; } - constexpr size_type rfind(const value_type* s, - size_type pos, - size_type n) const { + constexpr size_type rfind(const CharT* s, size_type pos, size_type n) const { return rfind(BasicStringPiece(s, n), pos); } - constexpr size_type rfind(const value_type* s, size_type pos = npos) const { + constexpr size_type rfind(const CharT* s, size_type pos = npos) const { return rfind(BasicStringPiece(s), pos); } @@ -318,19 +310,17 @@ return internal::find_first_of(*this, s, pos); } - constexpr size_type find_first_of(value_type c, - size_type pos = 0) const noexcept { + constexpr size_type find_first_of(CharT c, size_type pos = 0) const noexcept { return find(c, pos); } - constexpr size_type find_first_of(const value_type* s, + constexpr size_type find_first_of(const CharT* s, size_type pos, size_type n) const { return find_first_of(BasicStringPiece(s, n), pos); } - constexpr size_type find_first_of(const value_type* s, - size_type pos = 0) const { + constexpr size_type find_first_of(const CharT* s, size_type pos = 0) const { return find_first_of(BasicStringPiece(s), pos); } @@ -340,19 +330,18 @@ return internal::find_last_of(*this, s, pos); } - constexpr size_type find_last_of(value_type c, + constexpr size_type find_last_of(CharT c, size_type pos = npos) const noexcept { return rfind(c, pos); } - constexpr size_type find_last_of(const value_type* s, + constexpr size_type find_last_of(const CharT* s, size_type pos, size_type n) const { return find_last_of(BasicStringPiece(s, n), pos); } - constexpr size_type find_last_of(const value_type* s, - size_type pos = npos) const { + constexpr size_type find_last_of(const CharT* s, size_type pos = npos) const { return find_last_of(BasicStringPiece(s), pos); } @@ -362,7 +351,7 @@ return internal::find_first_not_of(*this, s, pos); } - constexpr size_type find_first_not_of(value_type c, + constexpr size_type find_first_not_of(CharT c, size_type pos = 0) const noexcept { if (empty()) return npos; @@ -374,13 +363,13 @@ return npos; } - constexpr size_type find_first_not_of(const value_type* s, + constexpr size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const { return find_first_not_of(BasicStringPiece(s, n), pos); } - constexpr size_type find_first_not_of(const value_type* s, + constexpr size_type find_first_not_of(const CharT* s, size_type pos = 0) const { return find_first_not_of(BasicStringPiece(s), pos); } @@ -391,7 +380,7 @@ return internal::find_last_not_of(*this, s, pos); } - constexpr size_type find_last_not_of(value_type c, + constexpr size_type find_last_not_of(CharT c, size_type pos = npos) const noexcept { if (empty()) return npos; @@ -405,38 +394,38 @@ return npos; } - constexpr size_type find_last_not_of(const value_type* s, + constexpr size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const { return find_last_not_of(BasicStringPiece(s, n), pos); } - constexpr size_type find_last_not_of(const value_type* s, + constexpr size_type find_last_not_of(const CharT* s, size_type pos = npos) const { return find_last_not_of(BasicStringPiece(s), pos); } protected: - const value_type* ptr_; + const CharT* ptr_; size_type length_; }; -template <typename STRING_TYPE> -const typename BasicStringPiece<STRING_TYPE>::size_type -BasicStringPiece<STRING_TYPE>::npos = - typename BasicStringPiece<STRING_TYPE>::size_type(-1); +template <typename CharT> +const typename BasicStringPiece<CharT>::size_type + BasicStringPiece<CharT>::npos = + typename BasicStringPiece<CharT>::size_type(-1); // MSVC doesn't like complex extern templates and DLLs. #if !defined(COMPILER_MSVC) -extern template class BASE_EXPORT BasicStringPiece<std::string>; -extern template class BASE_EXPORT BasicStringPiece<std::u16string>; +extern template class BASE_EXPORT BasicStringPiece<char>; +extern template class BASE_EXPORT BasicStringPiece<char16_t>; #endif // Comparison operators -------------------------------------------------------- // operator == -template <typename StringT> -constexpr bool operator==(BasicStringPiece<StringT> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT> +constexpr bool operator==(BasicStringPiece<CharT> lhs, + BasicStringPiece<CharT> rhs) noexcept { return lhs.size() == rhs.size() && lhs.compare(rhs) == 0; } @@ -446,116 +435,116 @@ // https://wg21.link/n3766 for details. // Furthermore, we require dummy template parameters for these overloads to work // around a name mangling issue on Windows. -template <typename StringT, int = 1> +template <typename CharT, int = 1> constexpr bool operator==( - BasicStringPiece<StringT> lhs, - std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept { + BasicStringPiece<CharT> lhs, + std::common_type_t<BasicStringPiece<CharT>> rhs) noexcept { return lhs.size() == rhs.size() && lhs.compare(rhs) == 0; } -template <typename StringT, int = 2> -constexpr bool operator==(std::common_type_t<BasicStringPiece<StringT>> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT, int = 2> +constexpr bool operator==(std::common_type_t<BasicStringPiece<CharT>> lhs, + BasicStringPiece<CharT> rhs) noexcept { return lhs.size() == rhs.size() && lhs.compare(rhs) == 0; } // operator != -template <typename StringT> -constexpr bool operator!=(BasicStringPiece<StringT> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT> +constexpr bool operator!=(BasicStringPiece<CharT> lhs, + BasicStringPiece<CharT> rhs) noexcept { return !(lhs == rhs); } -template <typename StringT, int = 1> +template <typename CharT, int = 1> constexpr bool operator!=( - BasicStringPiece<StringT> lhs, - std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept { + BasicStringPiece<CharT> lhs, + std::common_type_t<BasicStringPiece<CharT>> rhs) noexcept { return !(lhs == rhs); } -template <typename StringT, int = 2> -constexpr bool operator!=(std::common_type_t<BasicStringPiece<StringT>> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT, int = 2> +constexpr bool operator!=(std::common_type_t<BasicStringPiece<CharT>> lhs, + BasicStringPiece<CharT> rhs) noexcept { return !(lhs == rhs); } // operator < -template <typename StringT> -constexpr bool operator<(BasicStringPiece<StringT> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT> +constexpr bool operator<(BasicStringPiece<CharT> lhs, + BasicStringPiece<CharT> rhs) noexcept { return lhs.compare(rhs) < 0; } -template <typename StringT, int = 1> +template <typename CharT, int = 1> constexpr bool operator<( - BasicStringPiece<StringT> lhs, - std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept { + BasicStringPiece<CharT> lhs, + std::common_type_t<BasicStringPiece<CharT>> rhs) noexcept { return lhs.compare(rhs) < 0; } -template <typename StringT, int = 2> -constexpr bool operator<(std::common_type_t<BasicStringPiece<StringT>> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT, int = 2> +constexpr bool operator<(std::common_type_t<BasicStringPiece<CharT>> lhs, + BasicStringPiece<CharT> rhs) noexcept { return lhs.compare(rhs) < 0; } // operator > -template <typename StringT> -constexpr bool operator>(BasicStringPiece<StringT> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT> +constexpr bool operator>(BasicStringPiece<CharT> lhs, + BasicStringPiece<CharT> rhs) noexcept { return rhs < lhs; } -template <typename StringT, int = 1> +template <typename CharT, int = 1> constexpr bool operator>( - BasicStringPiece<StringT> lhs, - std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept { + BasicStringPiece<CharT> lhs, + std::common_type_t<BasicStringPiece<CharT>> rhs) noexcept { return rhs < lhs; } -template <typename StringT, int = 2> -constexpr bool operator>(std::common_type_t<BasicStringPiece<StringT>> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT, int = 2> +constexpr bool operator>(std::common_type_t<BasicStringPiece<CharT>> lhs, + BasicStringPiece<CharT> rhs) noexcept { return rhs < lhs; } // operator <= -template <typename StringT> -constexpr bool operator<=(BasicStringPiece<StringT> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT> +constexpr bool operator<=(BasicStringPiece<CharT> lhs, + BasicStringPiece<CharT> rhs) noexcept { return !(rhs < lhs); } -template <typename StringT, int = 1> +template <typename CharT, int = 1> constexpr bool operator<=( - BasicStringPiece<StringT> lhs, - std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept { + BasicStringPiece<CharT> lhs, + std::common_type_t<BasicStringPiece<CharT>> rhs) noexcept { return !(rhs < lhs); } -template <typename StringT, int = 2> -constexpr bool operator<=(std::common_type_t<BasicStringPiece<StringT>> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT, int = 2> +constexpr bool operator<=(std::common_type_t<BasicStringPiece<CharT>> lhs, + BasicStringPiece<CharT> rhs) noexcept { return !(rhs < lhs); } // operator >= -template <typename StringT> -constexpr bool operator>=(BasicStringPiece<StringT> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT> +constexpr bool operator>=(BasicStringPiece<CharT> lhs, + BasicStringPiece<CharT> rhs) noexcept { return !(lhs < rhs); } -template <typename StringT, int = 1> +template <typename CharT, int = 1> constexpr bool operator>=( - BasicStringPiece<StringT> lhs, - std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept { + BasicStringPiece<CharT> lhs, + std::common_type_t<BasicStringPiece<CharT>> rhs) noexcept { return !(lhs < rhs); } -template <typename StringT, int = 2> -constexpr bool operator>=(std::common_type_t<BasicStringPiece<StringT>> lhs, - BasicStringPiece<StringT> rhs) noexcept { +template <typename CharT, int = 2> +constexpr bool operator>=(std::common_type_t<BasicStringPiece<CharT>> lhs, + BasicStringPiece<CharT> rhs) noexcept { return !(lhs < rhs); }
diff --git a/base/strings/string_piece_forward.h b/base/strings/string_piece_forward.h index fe58a578..54dc572 100644 --- a/base/strings/string_piece_forward.h +++ b/base/strings/string_piece_forward.h
@@ -7,16 +7,13 @@ #ifndef BASE_STRINGS_STRING_PIECE_FORWARD_H_ #define BASE_STRINGS_STRING_PIECE_FORWARD_H_ -#include <string> - - namespace base { -template <typename STRING_TYPE> +template <typename CharT> class BasicStringPiece; -typedef BasicStringPiece<std::string> StringPiece; -typedef BasicStringPiece<std::u16string> StringPiece16; -typedef BasicStringPiece<std::wstring> WStringPiece; +typedef BasicStringPiece<char> StringPiece; +typedef BasicStringPiece<char16_t> StringPiece16; +typedef BasicStringPiece<wchar_t> WStringPiece; } // namespace base
diff --git a/base/strings/string_piece_unittest.cc b/base/strings/string_piece_unittest.cc index eaf9a38..6f0deaef 100644 --- a/base/strings/string_piece_unittest.cc +++ b/base/strings/string_piece_unittest.cc
@@ -12,37 +12,35 @@ namespace base { -template <typename T> +template <typename CharT> class CommonStringPieceTest : public ::testing::Test { public: - static const T as_string(const char* input) { - return T(input); - } - static const T& as_string(const T& input) { + static std::string as_string(const char* input) { return input; } + static const std::string& as_string(const std::string& input) { return input; } }; template <> -class CommonStringPieceTest<std::u16string> : public ::testing::Test { +class CommonStringPieceTest<char16_t> : public ::testing::Test { public: - static const std::u16string as_string(const char* input) { - return ASCIIToUTF16(input); + static std::u16string as_string(const char* input) { + return UTF8ToUTF16(input); } - static const std::u16string as_string(const std::string& input) { - return ASCIIToUTF16(input); + static std::u16string as_string(const std::string& input) { + return UTF8ToUTF16(input); } }; -typedef ::testing::Types<std::string, std::u16string> SupportedStringTypes; +typedef ::testing::Types<char, char16_t> SupportedCharTypes; -TYPED_TEST_SUITE(CommonStringPieceTest, SupportedStringTypes); +TYPED_TEST_SUITE(CommonStringPieceTest, SupportedCharTypes); TYPED_TEST(CommonStringPieceTest, CheckComparisonOperators) { #define CMP_Y(op, x, y) \ { \ - TypeParam lhs(TestFixture::as_string(x)); \ - TypeParam rhs(TestFixture::as_string(y)); \ + std::basic_string<TypeParam> lhs(TestFixture::as_string(x)); \ + std::basic_string<TypeParam> rhs(TestFixture::as_string(y)); \ ASSERT_TRUE((BasicStringPiece<TypeParam>((lhs.c_str())) \ op BasicStringPiece<TypeParam>((rhs.c_str())))); \ ASSERT_TRUE(BasicStringPiece<TypeParam>(lhs) op rhs); \ @@ -54,8 +52,8 @@ #define CMP_N(op, x, y) \ { \ - TypeParam lhs(TestFixture::as_string(x)); \ - TypeParam rhs(TestFixture::as_string(y)); \ + std::basic_string<TypeParam> lhs(TestFixture::as_string(x)); \ + std::basic_string<TypeParam> rhs(TestFixture::as_string(y)); \ ASSERT_FALSE((BasicStringPiece<TypeParam>((lhs.c_str())) \ op BasicStringPiece<TypeParam>((rhs.c_str())))); \ ASSERT_FALSE(BasicStringPiece<TypeParam>(lhs) op rhs); \ @@ -140,39 +138,39 @@ } TYPED_TEST(CommonStringPieceTest, CheckSTL) { - TypeParam alphabet(TestFixture::as_string("abcdefghijklmnopqrstuvwxyz")); - TypeParam abc(TestFixture::as_string("abc")); - TypeParam xyz(TestFixture::as_string("xyz")); - TypeParam foobar(TestFixture::as_string("foobar")); + std::basic_string<TypeParam> alphabet( + TestFixture::as_string("abcdefghijklmnopqrstuvwxyz")); + std::basic_string<TypeParam> abc(TestFixture::as_string("abc")); + std::basic_string<TypeParam> xyz(TestFixture::as_string("xyz")); + std::basic_string<TypeParam> foobar(TestFixture::as_string("foobar")); BasicStringPiece<TypeParam> a(alphabet); BasicStringPiece<TypeParam> b(abc); BasicStringPiece<TypeParam> c(xyz); BasicStringPiece<TypeParam> d(foobar); BasicStringPiece<TypeParam> e; - TypeParam temp(TestFixture::as_string("123")); - temp += static_cast<typename TypeParam::value_type>(0); + std::basic_string<TypeParam> temp(TestFixture::as_string("123")); + temp += static_cast<TypeParam>(0); temp += TestFixture::as_string("456"); BasicStringPiece<TypeParam> f(temp); - ASSERT_EQ(a[6], static_cast<typename TypeParam::value_type>('g')); - ASSERT_EQ(b[0], static_cast<typename TypeParam::value_type>('a')); - ASSERT_EQ(c[2], static_cast<typename TypeParam::value_type>('z')); - ASSERT_EQ(f[3], static_cast<typename TypeParam::value_type>('\0')); - ASSERT_EQ(f[5], static_cast<typename TypeParam::value_type>('5')); + ASSERT_EQ(a[6], static_cast<TypeParam>('g')); + ASSERT_EQ(b[0], static_cast<TypeParam>('a')); + ASSERT_EQ(c[2], static_cast<TypeParam>('z')); + ASSERT_EQ(f[3], static_cast<TypeParam>('\0')); + ASSERT_EQ(f[5], static_cast<TypeParam>('5')); - ASSERT_EQ(*d.data(), static_cast<typename TypeParam::value_type>('f')); - ASSERT_EQ(d.data()[5], static_cast<typename TypeParam::value_type>('r')); + ASSERT_EQ(*d.data(), static_cast<TypeParam>('f')); + ASSERT_EQ(d.data()[5], static_cast<TypeParam>('r')); ASSERT_EQ(e.data(), nullptr); - ASSERT_EQ(*a.begin(), static_cast<typename TypeParam::value_type>('a')); - ASSERT_EQ(*(b.begin() + 2), static_cast<typename TypeParam::value_type>('c')); - ASSERT_EQ(*(c.end() - 1), static_cast<typename TypeParam::value_type>('z')); + ASSERT_EQ(*a.begin(), static_cast<TypeParam>('a')); + ASSERT_EQ(*(b.begin() + 2), static_cast<TypeParam>('c')); + ASSERT_EQ(*(c.end() - 1), static_cast<TypeParam>('z')); - ASSERT_EQ(*a.rbegin(), static_cast<typename TypeParam::value_type>('z')); - ASSERT_EQ(*(b.rbegin() + 2), - static_cast<typename TypeParam::value_type>('a')); - ASSERT_EQ(*(c.rend() - 1), static_cast<typename TypeParam::value_type>('x')); + ASSERT_EQ(*a.rbegin(), static_cast<TypeParam>('z')); + ASSERT_EQ(*(b.rbegin() + 2), static_cast<TypeParam>('a')); + ASSERT_EQ(*(c.rend() - 1), static_cast<TypeParam>('x')); ASSERT_EQ(a.rbegin() + 26, a.rend()); ASSERT_EQ(a.size(), 26U); @@ -202,10 +200,11 @@ TYPED_TEST(CommonStringPieceTest, CheckFind) { typedef BasicStringPiece<TypeParam> Piece; - TypeParam alphabet(TestFixture::as_string("abcdefghijklmnopqrstuvwxyz")); - TypeParam abc(TestFixture::as_string("abc")); - TypeParam xyz(TestFixture::as_string("xyz")); - TypeParam foobar(TestFixture::as_string("foobar")); + std::basic_string<TypeParam> alphabet( + TestFixture::as_string("abcdefghijklmnopqrstuvwxyz")); + std::basic_string<TypeParam> abc(TestFixture::as_string("abc")); + std::basic_string<TypeParam> xyz(TestFixture::as_string("xyz")); + std::basic_string<TypeParam> foobar(TestFixture::as_string("foobar")); BasicStringPiece<TypeParam> a(alphabet); BasicStringPiece<TypeParam> b(abc); @@ -214,12 +213,12 @@ d = Piece(); Piece e; - TypeParam temp(TestFixture::as_string("123")); + std::basic_string<TypeParam> temp(TestFixture::as_string("123")); temp.push_back('\0'); temp += TestFixture::as_string("456"); Piece f(temp); - typename TypeParam::value_type buf[4] = { '%', '%', '%', '%' }; + TypeParam buf[4] = {'%', '%', '%', '%'}; ASSERT_EQ(a.copy(buf, 4), 4U); ASSERT_EQ(buf[0], a[0]); ASSERT_EQ(buf[1], a[1]); @@ -236,7 +235,7 @@ ASSERT_EQ(buf[2], c[2]); ASSERT_EQ(buf[3], a[3]); - ASSERT_EQ(Piece::npos, TypeParam::npos); + ASSERT_EQ(Piece::npos, std::basic_string<TypeParam>::npos); ASSERT_EQ(a.find(b), 0U); ASSERT_EQ(a.find(b, 1), Piece::npos); @@ -249,7 +248,8 @@ ASSERT_EQ(a.find(e), 0U); ASSERT_EQ(a.find(d, 12), 12U); ASSERT_EQ(a.find(e, 17), 17U); - TypeParam not_found(TestFixture::as_string("xx not found bb")); + std::basic_string<TypeParam> not_found( + TestFixture::as_string("xx not found bb")); Piece g(not_found); ASSERT_EQ(a.find(g), Piece::npos); // empty string nonsense @@ -258,7 +258,8 @@ ASSERT_EQ(d.find(b, 4), Piece::npos); ASSERT_EQ(e.find(b, 7), Piece::npos); - size_t empty_search_pos = TypeParam().find(TypeParam()); + size_t empty_search_pos = + std::basic_string<TypeParam>().find(std::basic_string<TypeParam>()); ASSERT_EQ(d.find(d), empty_search_pos); ASSERT_EQ(d.find(e), empty_search_pos); ASSERT_EQ(e.find(d), empty_search_pos); @@ -268,7 +269,7 @@ ASSERT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); ASSERT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); - constexpr typename TypeParam::value_type kNul = '\0'; + constexpr TypeParam kNul = '\0'; ASSERT_EQ(a.find('a'), 0U); ASSERT_EQ(a.find('c'), 2U); ASSERT_EQ(a.find('z'), 25U); @@ -328,10 +329,14 @@ ASSERT_EQ(a.rfind(c, 0U), Piece::npos); ASSERT_EQ(b.rfind(c), Piece::npos); ASSERT_EQ(b.rfind(c, 0U), Piece::npos); - ASSERT_EQ(a.rfind(d), static_cast<size_t>(a.rfind(TypeParam()))); - ASSERT_EQ(a.rfind(e), a.rfind(TypeParam())); - ASSERT_EQ(a.rfind(d), static_cast<size_t>(TypeParam(a).rfind(TypeParam()))); - ASSERT_EQ(a.rfind(e), TypeParam(a).rfind(TypeParam())); + ASSERT_EQ(a.rfind(d), + static_cast<size_t>(a.rfind(std::basic_string<TypeParam>()))); + ASSERT_EQ(a.rfind(e), a.rfind(std::basic_string<TypeParam>())); + ASSERT_EQ(a.rfind(d), + static_cast<size_t>(std::basic_string<TypeParam>(a).rfind( + std::basic_string<TypeParam>()))); + ASSERT_EQ(a.rfind(e), std::basic_string<TypeParam>(a).rfind( + std::basic_string<TypeParam>())); ASSERT_EQ(a.rfind(d, 12), 12U); ASSERT_EQ(a.rfind(e, 17), 17U); ASSERT_EQ(a.rfind(g), Piece::npos); @@ -380,8 +385,9 @@ ASSERT_EQ(d.rfind(e.data(), 4), std::string().rfind(std::string())); ASSERT_EQ(e.rfind(e.data(), 7), std::string().rfind(std::string())); - TypeParam one_two_three_four(TestFixture::as_string("one,two:three;four")); - TypeParam comma_colon(TestFixture::as_string(",:")); + std::basic_string<TypeParam> one_two_three_four( + TestFixture::as_string("one,two:three;four")); + std::basic_string<TypeParam> comma_colon(TestFixture::as_string(",:")); ASSERT_EQ(3U, Piece(one_two_three_four).find_first_of(comma_colon)); ASSERT_EQ(a.find_first_of(b), 0U); ASSERT_EQ(a.find_first_of(b, 0), 0U); @@ -423,7 +429,7 @@ ASSERT_EQ(d.find_first_not_of(e), Piece::npos); ASSERT_EQ(e.find_first_not_of(e), Piece::npos); - TypeParam equals(TestFixture::as_string("====")); + std::basic_string<TypeParam> equals(TestFixture::as_string("====")); Piece h(equals); ASSERT_EQ(h.find_first_not_of('='), Piece::npos); ASSERT_EQ(h.find_first_not_of('=', 3), Piece::npos); @@ -439,7 +445,7 @@ ASSERT_EQ(e.find_first_not_of(kNul), Piece::npos); // Piece g("xx not found bb"); - TypeParam fifty_six(TestFixture::as_string("56")); + std::basic_string<TypeParam> fifty_six(TestFixture::as_string("56")); Piece i(fifty_six); ASSERT_EQ(h.find_last_of(a), Piece::npos); ASSERT_EQ(g.find_last_of(a), g.size()-1); @@ -524,14 +530,14 @@ } TYPED_TEST(CommonStringPieceTest, CheckCustom) { - TypeParam foobar(TestFixture::as_string("foobar")); + std::basic_string<TypeParam> foobar(TestFixture::as_string("foobar")); BasicStringPiece<TypeParam> a(foobar); - TypeParam s1(TestFixture::as_string("123")); - s1 += static_cast<typename TypeParam::value_type>('\0'); + std::basic_string<TypeParam> s1(TestFixture::as_string("123")); + s1 += static_cast<TypeParam>('\0'); s1 += TestFixture::as_string("456"); BasicStringPiece<TypeParam> b(s1); BasicStringPiece<TypeParam> e; - TypeParam s2; + std::basic_string<TypeParam> s2; // remove_prefix BasicStringPiece<TypeParam> c(a); @@ -564,9 +570,10 @@ ASSERT_NE(c, a); // operator STRING_TYPE() - TypeParam s5(TypeParam(a).c_str(), 7); // Note, has an embedded NULL + std::basic_string<TypeParam> s5(std::basic_string<TypeParam>(a).c_str(), + 7); // Note, has an embedded NULL ASSERT_EQ(c, s5); - TypeParam s6(e); + std::basic_string<TypeParam> s6(e); ASSERT_TRUE(s6.empty()); } @@ -593,15 +600,18 @@ ASSERT_EQ(s.data(), nullptr); ASSERT_EQ(s.size(), 0U); - TypeParam str(s); + std::basic_string<TypeParam> str(s); ASSERT_EQ(str.length(), 0U); - ASSERT_EQ(str, TypeParam()); + ASSERT_EQ(str, std::basic_string<TypeParam>()); } TYPED_TEST(CommonStringPieceTest, CheckComparisons2) { - TypeParam alphabet(TestFixture::as_string("abcdefghijklmnopqrstuvwxyz")); - TypeParam alphabet_z(TestFixture::as_string("abcdefghijklmnopqrstuvwxyzz")); - TypeParam alphabet_y(TestFixture::as_string("abcdefghijklmnopqrstuvwxyy")); + std::basic_string<TypeParam> alphabet( + TestFixture::as_string("abcdefghijklmnopqrstuvwxyz")); + std::basic_string<TypeParam> alphabet_z( + TestFixture::as_string("abcdefghijklmnopqrstuvwxyzz")); + std::basic_string<TypeParam> alphabet_y( + TestFixture::as_string("abcdefghijklmnopqrstuvwxyy")); BasicStringPiece<TypeParam> abc(alphabet); // check comparison operations on strings longer than 4 bytes. @@ -623,7 +633,7 @@ } TYPED_TEST(CommonStringPieceTest, HeterogenousStringPieceEquals) { - TypeParam hello(TestFixture::as_string("hello")); + std::basic_string<TypeParam> hello(TestFixture::as_string("hello")); ASSERT_EQ(BasicStringPiece<TypeParam>(hello), hello); ASSERT_EQ(hello.c_str(), BasicStringPiece<TypeParam>(hello)); @@ -653,8 +663,8 @@ } TYPED_TEST(CommonStringPieceTest, CheckConstructors) { - TypeParam str(TestFixture::as_string("hello world")); - TypeParam empty; + std::basic_string<TypeParam> str(TestFixture::as_string("hello world")); + std::basic_string<TypeParam> empty; ASSERT_EQ(str, BasicStringPiece<TypeParam>(str)); ASSERT_EQ(str, BasicStringPiece<TypeParam>(str.c_str()));
diff --git a/base/strings/string_split_internal.h b/base/strings/string_split_internal.h index 2eff3de..d5bf462 100644 --- a/base/strings/string_split_internal.h +++ b/base/strings/string_split_internal.h
@@ -15,24 +15,24 @@ namespace internal { // Returns either the ASCII or UTF-16 whitespace. -template <typename Str> -BasicStringPiece<Str> WhitespaceForType(); +template <typename CharT> +BasicStringPiece<CharT> WhitespaceForType(); template <> -inline StringPiece16 WhitespaceForType<std::u16string>() { +inline StringPiece16 WhitespaceForType<char16_t>() { return kWhitespaceUTF16; } template <> -inline StringPiece WhitespaceForType<std::string>() { +inline StringPiece WhitespaceForType<char>() { return kWhitespaceASCII; } // General string splitter template. Can take 8- or 16-bit input, can produce // the corresponding string or StringPiece output. -template <typename OutputStringType, typename Str> +template <typename OutputStringType, typename CharT> static std::vector<OutputStringType> SplitStringT( - BasicStringPiece<Str> str, - BasicStringPiece<Str> delimiter, + BasicStringPiece<CharT> str, + BasicStringPiece<CharT> delimiter, WhitespaceHandling whitespace, SplitResult result_type) { std::vector<OutputStringType> result; @@ -40,20 +40,20 @@ return result; size_t start = 0; - while (start != Str::npos) { + while (start != std::basic_string<CharT>::npos) { size_t end = str.find_first_of(delimiter, start); - BasicStringPiece<Str> piece; - if (end == Str::npos) { + BasicStringPiece<CharT> piece; + if (end == std::basic_string<CharT>::npos) { piece = str.substr(start); - start = Str::npos; + start = std::basic_string<CharT>::npos; } else { piece = str.substr(start, end - start); start = end + 1; } if (whitespace == TRIM_WHITESPACE) - piece = TrimString(piece, WhitespaceForType<Str>(), TRIM_ALL); + piece = TrimString(piece, WhitespaceForType<CharT>(), TRIM_ALL); if (result_type == SPLIT_WANT_ALL || !piece.empty()) result.emplace_back(piece); @@ -61,13 +61,13 @@ return result; } -template <typename OutputStringType, typename Str> +template <typename OutputStringType, typename CharT> std::vector<OutputStringType> SplitStringUsingSubstrT( - BasicStringPiece<Str> input, - BasicStringPiece<Str> delimiter, + BasicStringPiece<CharT> input, + BasicStringPiece<CharT> delimiter, WhitespaceHandling whitespace, SplitResult result_type) { - using Piece = BasicStringPiece<Str>; + using Piece = BasicStringPiece<CharT>; using size_type = typename Piece::size_type; std::vector<OutputStringType> result; @@ -84,7 +84,7 @@ : input.substr(begin_index, end_index - begin_index); if (whitespace == TRIM_WHITESPACE) - term = TrimString(term, WhitespaceForType<Str>(), TRIM_ALL); + term = TrimString(term, WhitespaceForType<CharT>(), TRIM_ALL); if (result_type == SPLIT_WANT_ALL || !term.empty()) result.emplace_back(term);
diff --git a/base/strings/string_split_win.cc b/base/strings/string_split_win.cc index ec06b42..2820842 100644 --- a/base/strings/string_split_win.cc +++ b/base/strings/string_split_win.cc
@@ -15,7 +15,7 @@ namespace internal { template <> -inline WStringPiece WhitespaceForType<std::wstring>() { +inline WStringPiece WhitespaceForType<wchar_t>() { return kWhitespaceWide; }
diff --git a/base/strings/string_tokenizer.h b/base/strings/string_tokenizer.h index 9b1d42b..9e6f3bd 100644 --- a/base/strings/string_tokenizer.h +++ b/base/strings/string_tokenizer.h
@@ -190,9 +190,8 @@ const_iterator token_begin() const { return token_begin_; } const_iterator token_end() const { return token_end_; } str token() const { return str(token_begin_, token_end_); } - BasicStringPiece<str> token_piece() const { - return BasicStringPiece<str>(&*token_begin_, - std::distance(token_begin_, token_end_)); + BasicStringPiece<char_type> token_piece() const { + return MakeBasicStringPiece<char_type>(token_begin_, token_end_); } private:
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc index f6d9aaf..fe6e78f9 100644 --- a/base/strings/string_util.cc +++ b/base/strings/string_util.cc
@@ -358,7 +358,7 @@ StringPiece16 find_this, StringPiece16 replace_with) { internal::DoReplaceMatchesAfterOffset( - str, start_offset, internal::SubstringMatcher<std::u16string>{find_this}, + str, start_offset, internal::MakeSubstringMatcher(find_this), replace_with, internal::ReplaceType::REPLACE_FIRST); } @@ -367,7 +367,7 @@ StringPiece find_this, StringPiece replace_with) { internal::DoReplaceMatchesAfterOffset( - str, start_offset, internal::SubstringMatcher<std::string>{find_this}, + str, start_offset, internal::MakeSubstringMatcher(find_this), replace_with, internal::ReplaceType::REPLACE_FIRST); } @@ -376,7 +376,7 @@ StringPiece16 find_this, StringPiece16 replace_with) { internal::DoReplaceMatchesAfterOffset( - str, start_offset, internal::SubstringMatcher<std::u16string>{find_this}, + str, start_offset, internal::MakeSubstringMatcher(find_this), replace_with, internal::ReplaceType::REPLACE_ALL); } @@ -385,7 +385,7 @@ StringPiece find_this, StringPiece replace_with) { internal::DoReplaceMatchesAfterOffset( - str, start_offset, internal::SubstringMatcher<std::string>{find_this}, + str, start_offset, internal::MakeSubstringMatcher(find_this), replace_with, internal::ReplaceType::REPLACE_ALL); }
diff --git a/base/strings/string_util.h b/base/strings/string_util.h index fe791d8..ab8d4fd 100644 --- a/base/strings/string_util.h +++ b/base/strings/string_util.h
@@ -85,8 +85,8 @@ // Simplified implementation of C++20's std::basic_string_view(It, End). // Reference: https://wg21.link/string.view.cons -template <typename StringT, typename Iter> -constexpr BasicStringPiece<StringT> MakeBasicStringPiece(Iter begin, Iter end) { +template <typename CharT, typename Iter> +constexpr BasicStringPiece<CharT> MakeBasicStringPiece(Iter begin, Iter end) { DCHECK_GE(end - begin, 0); return {base::to_address(begin), static_cast<size_t>(end - begin)}; } @@ -95,17 +95,17 @@ // aliases defined in base/strings/string_piece_forward.h template <typename Iter> constexpr StringPiece MakeStringPiece(Iter begin, Iter end) { - return MakeBasicStringPiece<std::string>(begin, end); + return MakeBasicStringPiece<char>(begin, end); } template <typename Iter> constexpr StringPiece16 MakeStringPiece16(Iter begin, Iter end) { - return MakeBasicStringPiece<std::u16string>(begin, end); + return MakeBasicStringPiece<char16_t>(begin, end); } template <typename Iter> constexpr WStringPiece MakeWStringPiece(Iter begin, Iter end) { - return MakeBasicStringPiece<std::wstring>(begin, end); + return MakeBasicStringPiece<wchar_t>(begin, end); } // ASCII-specific tolower. The standard library's tolower is locale sensitive,
diff --git a/base/strings/string_util_internal.h b/base/strings/string_util_internal.h index 9385160..3c64603 100644 --- a/base/strings/string_util_internal.h +++ b/base/strings/string_util_internal.h
@@ -43,34 +43,34 @@ return !(reinterpret_cast<MachineWord>(pointer) & (sizeof(MachineWord) - 1)); } -template <typename StringType> -StringType ToLowerASCIIImpl(BasicStringPiece<StringType> str) { - StringType ret; +template <typename CharT> +std::basic_string<CharT> ToLowerASCIIImpl(BasicStringPiece<CharT> str) { + std::basic_string<CharT> ret; ret.reserve(str.size()); for (size_t i = 0; i < str.size(); i++) ret.push_back(ToLowerASCII(str[i])); return ret; } -template <typename StringType> -StringType ToUpperASCIIImpl(BasicStringPiece<StringType> str) { - StringType ret; +template <typename CharT> +std::basic_string<CharT> ToUpperASCIIImpl(BasicStringPiece<CharT> str) { + std::basic_string<CharT> ret; ret.reserve(str.size()); for (size_t i = 0; i < str.size(); i++) ret.push_back(ToUpperASCII(str[i])); return ret; } -template <class StringType> -int CompareCaseInsensitiveASCIIT(BasicStringPiece<StringType> a, - BasicStringPiece<StringType> b) { +template <class CharT> +int CompareCaseInsensitiveASCIIT(BasicStringPiece<CharT> a, + BasicStringPiece<CharT> b) { // Find the first characters that aren't equal and compare them. If the end // of one of the strings is found before a nonequal character, the lengths // of the strings are compared. size_t i = 0; while (i < a.length() && i < b.length()) { - typename StringType::value_type lower_a = ToLowerASCII(a[i]); - typename StringType::value_type lower_b = ToLowerASCII(b[i]); + CharT lower_a = ToLowerASCII(a[i]); + CharT lower_b = ToLowerASCII(b[i]); if (lower_a < lower_b) return -1; if (lower_a > lower_b) @@ -88,11 +88,11 @@ return 1; } -template <typename Str> -TrimPositions TrimStringT(BasicStringPiece<Str> input, - BasicStringPiece<Str> trim_chars, +template <typename CharT> +TrimPositions TrimStringT(BasicStringPiece<CharT> input, + BasicStringPiece<CharT> trim_chars, TrimPositions positions, - Str* output) { + std::basic_string<CharT>* output) { // Find the edges of leading/trailing whitespace as desired. Need to use // a StringPiece version of input to be able to call find* on it with the // StringPiece version of trim_chars (normally the trim_chars will be a @@ -107,8 +107,8 @@ // When the string was all trimmed, report that we stripped off characters // from whichever position the caller was interested in. For empty input, we // stripped no characters, but we still need to clear |output|. - if (input.empty() || first_good_char == Str::npos || - last_good_char == Str::npos) { + if (input.empty() || first_good_char == std::basic_string<CharT>::npos || + last_good_char == std::basic_string<CharT>::npos) { bool input_was_empty = input.empty(); // in case output == &input output->clear(); return input_was_empty ? TRIM_NONE : positions; @@ -124,10 +124,10 @@ (last_good_char == last_char ? TRIM_NONE : TRIM_TRAILING)); } -template <typename Str> -BasicStringPiece<Str> TrimStringPieceT(BasicStringPiece<Str> input, - BasicStringPiece<Str> trim_chars, - TrimPositions positions) { +template <typename CharT> +BasicStringPiece<CharT> TrimStringPieceT(BasicStringPiece<CharT> input, + BasicStringPiece<CharT> trim_chars, + TrimPositions positions) { size_t begin = (positions & TRIM_LEADING) ? input.find_first_not_of(trim_chars) : 0; size_t end = (positions & TRIM_TRAILING) @@ -136,10 +136,11 @@ return input.substr(std::min(begin, input.size()), end - begin); } -template <typename STR> -STR CollapseWhitespaceT(BasicStringPiece<STR> text, - bool trim_sequences_with_line_breaks) { - STR result; +template <typename CharT> +std::basic_string<CharT> CollapseWhitespaceT( + BasicStringPiece<CharT> text, + bool trim_sequences_with_line_breaks) { + std::basic_string<CharT> result; result.resize(text.size()); // Set flags to pretend we're already in a trimmed whitespace sequence, so we @@ -257,31 +258,30 @@ // The hardcoded strings are typically very short so it doesn't matter, and the // string piece gives additional flexibility for the caller (doesn't have to be // null terminated) so we choose the StringPiece route. -template <typename Str> -inline bool DoLowerCaseEqualsASCII(BasicStringPiece<Str> str, +template <typename CharT> +inline bool DoLowerCaseEqualsASCII(BasicStringPiece<CharT> str, StringPiece lowercase_ascii) { return std::equal( str.begin(), str.end(), lowercase_ascii.begin(), lowercase_ascii.end(), [](auto lhs, auto rhs) { return ToLowerASCII(lhs) == rhs; }); } -template <typename Str> -bool StartsWithT(BasicStringPiece<Str> str, - BasicStringPiece<Str> search_for, +template <typename CharT> +bool StartsWithT(BasicStringPiece<CharT> str, + BasicStringPiece<CharT> search_for, CompareCase case_sensitivity) { if (search_for.size() > str.size()) return false; - BasicStringPiece<Str> source = str.substr(0, search_for.size()); + BasicStringPiece<CharT> source = str.substr(0, search_for.size()); switch (case_sensitivity) { case CompareCase::SENSITIVE: return source == search_for; case CompareCase::INSENSITIVE_ASCII: - return std::equal( - search_for.begin(), search_for.end(), source.begin(), - CaseInsensitiveCompareASCII<typename Str::value_type>()); + return std::equal(search_for.begin(), search_for.end(), source.begin(), + CaseInsensitiveCompareASCII<CharT>()); default: NOTREACHED(); @@ -289,14 +289,14 @@ } } -template <typename Str> -bool EndsWithT(BasicStringPiece<Str> str, - BasicStringPiece<Str> search_for, +template <typename CharT> +bool EndsWithT(BasicStringPiece<CharT> str, + BasicStringPiece<CharT> search_for, CompareCase case_sensitivity) { if (search_for.size() > str.size()) return false; - BasicStringPiece<Str> source = + BasicStringPiece<CharT> source = str.substr(str.size() - search_for.size(), search_for.size()); switch (case_sensitivity) { @@ -304,9 +304,8 @@ return source == search_for; case CompareCase::INSENSITIVE_ASCII: - return std::equal( - source.begin(), source.end(), search_for.begin(), - CaseInsensitiveCompareASCII<typename Str::value_type>()); + return std::equal(source.begin(), source.end(), search_for.begin(), + CaseInsensitiveCompareASCII<CharT>()); default: NOTREACHED(); @@ -315,28 +314,40 @@ } // A Matcher for DoReplaceMatchesAfterOffset() that matches substrings. -template <class StringType> +template <class CharT> struct SubstringMatcher { - BasicStringPiece<StringType> find_this; + BasicStringPiece<CharT> find_this; - size_t Find(const StringType& input, size_t pos) { + size_t Find(const std::basic_string<CharT>& input, size_t pos) { return input.find(find_this.data(), pos, find_this.length()); } size_t MatchSize() { return find_this.length(); } }; -// A Matcher for DoReplaceMatchesAfterOffset() that matches single characters. -template <class StringType> -struct CharacterMatcher { - BasicStringPiece<StringType> find_any_of_these; +// Type deduction helper for SubstringMatcher. +template <class CharT> +auto MakeSubstringMatcher(BasicStringPiece<CharT> find_this) { + return SubstringMatcher<CharT>{find_this}; +} - size_t Find(const StringType& input, size_t pos) { +// A Matcher for DoReplaceMatchesAfterOffset() that matches single characters. +template <class CharT> +struct CharacterMatcher { + BasicStringPiece<CharT> find_any_of_these; + + size_t Find(const std::basic_string<CharT>& input, size_t pos) { return input.find_first_of(find_any_of_these.data(), pos, find_any_of_these.length()); } constexpr size_t MatchSize() { return 1; } }; +// Type deduction helper for CharacterMatcher. +template <class CharT> +auto MakeCharacterMatcher(BasicStringPiece<CharT> find_any_of_these) { + return CharacterMatcher<CharT>{find_any_of_these}; +} + enum class ReplaceType { REPLACE_ALL, REPLACE_FIRST }; // Runs in O(n) time in the length of |str|, and transforms the string without @@ -344,13 +355,13 @@ // // This is parameterized on a |Matcher| traits type, so that it can be the // implementation for both ReplaceChars() and ReplaceSubstringsAfterOffset(). -template <class StringType, class Matcher> -bool DoReplaceMatchesAfterOffset(StringType* str, +template <class CharT, class Matcher> +bool DoReplaceMatchesAfterOffset(std::basic_string<CharT>* str, size_t initial_offset, Matcher matcher, - BasicStringPiece<StringType> replace_with, + BasicStringPiece<CharT> replace_with, ReplaceType replace_type) { - using CharTraits = typename StringType::traits_type; + using CharTraits = std::char_traits<CharT>; const size_t find_length = matcher.MatchSize(); if (!find_length) @@ -358,7 +369,7 @@ // If the find string doesn't appear, there's nothing to do. size_t first_match = matcher.Find(*str, initial_offset); - if (first_match == StringType::npos) + if (first_match == std::basic_string<CharT>::npos) return false; // If we're only replacing one instance, there's no need to do anything @@ -373,7 +384,7 @@ // replace() on each instance, and finish the entire operation in O(n) time. if (find_length == replace_length) { auto* buffer = &((*str)[0]); - for (size_t offset = first_match; offset != StringType::npos; + for (size_t offset = first_match; offset != std::basic_string<CharT>::npos; offset = matcher.Find(*str, offset + replace_length)) { CharTraits::copy(buffer + offset, replace_with.data(), replace_length); } @@ -403,7 +414,7 @@ // matches. const size_t expansion_per_match = (replace_length - find_length); size_t num_matches = 0; - for (size_t match = first_match; match != StringType::npos; + for (size_t match = first_match; match != std::basic_string<CharT>::npos; match = matcher.Find(*str, match + find_length)) { expansion += expansion_per_match; ++num_matches; @@ -413,7 +424,7 @@ if (str->capacity() < final_length) { // If we'd have to allocate a new buffer to grow the string, build the // result directly into the new allocation via append(). - StringType src(str->get_allocator()); + std::basic_string<CharT> src(str->get_allocator()); str->swap(src); str->reserve(final_length); @@ -471,7 +482,8 @@ } read_offset += find_length; - // min() clamps StringType::npos (the largest unsigned value) to str_length. + // min() clamps std::basic_string<CharT>::npos (the largest unsigned value) + // to str_length. size_t match = std::min(matcher.Find(*str, read_offset), str_length); size_t length = match - read_offset; @@ -487,19 +499,19 @@ return true; } -template <class StringType> -bool ReplaceCharsT(BasicStringPiece<StringType> input, - BasicStringPiece<StringType> find_any_of_these, - BasicStringPiece<StringType> replace_with, - StringType* output) { +template <class CharT> +bool ReplaceCharsT(BasicStringPiece<CharT> input, + BasicStringPiece<CharT> find_any_of_these, + BasicStringPiece<CharT> replace_with, + std::basic_string<CharT>* output) { // Commonly, this is called with output and input being the same string; in // that case, skip the copy. if (input.data() != output->data() || input.size() != output->size()) output->assign(input.data(), input.size()); - return DoReplaceMatchesAfterOffset( - output, 0, CharacterMatcher<StringType>{find_any_of_these}, replace_with, - ReplaceType::REPLACE_ALL); + return DoReplaceMatchesAfterOffset(output, 0, + MakeCharacterMatcher(find_any_of_these), + replace_with, ReplaceType::REPLACE_ALL); } template <class string_type> @@ -513,20 +525,20 @@ // Generic version for all JoinString overloads. |list_type| must be a sequence // (base::span or std::initializer_list) of strings/StringPieces (std::string, -// std::u16string, StringPiece or StringPiece16). |string_type| is either -// std::string or std::u16string. -template <typename list_type, typename string_type> -static string_type JoinStringT(list_type parts, - BasicStringPiece<string_type> sep) { +// std::u16string, StringPiece or StringPiece16). |CharT| is either char or +// char16_t. +template <typename list_type, typename CharT> +static std::basic_string<CharT> JoinStringT(list_type parts, + BasicStringPiece<CharT> sep) { if (base::empty(parts)) - return string_type(); + return std::basic_string<CharT>(); // Pre-allocate the eventual size of the string. Start with the size of all of // the separators (note that this *assumes* parts.size() > 0). size_t total_size = (parts.size() - 1) * sep.size(); for (const auto& part : parts) total_size += part.size(); - string_type result; + std::basic_string<CharT> result; result.reserve(total_size); auto iter = parts.begin(); @@ -545,10 +557,10 @@ return result; } -template <class StringType> -StringType DoReplaceStringPlaceholders( - BasicStringPiece<StringType> format_string, - const std::vector<StringType>& subst, +template <class CharT> +std::basic_string<CharT> DoReplaceStringPlaceholders( + BasicStringPiece<CharT> format_string, + const std::vector<std::basic_string<CharT>>& subst, std::vector<size_t>* offsets) { size_t substitutions = subst.size(); DCHECK_LT(substitutions, 10U); @@ -557,7 +569,7 @@ for (const auto& cur : subst) sub_length += cur.length(); - StringType formatted; + std::basic_string<CharT> formatted; formatted.reserve(format_string.length() + sub_length); std::vector<ReplacementOffset> r_offsets;
diff --git a/base/strings/string_util_win.cc b/base/strings/string_util_win.cc index 3c2da65..72a0403c 100644 --- a/base/strings/string_util_win.cc +++ b/base/strings/string_util_win.cc
@@ -101,7 +101,7 @@ WStringPiece find_this, WStringPiece replace_with) { internal::DoReplaceMatchesAfterOffset( - str, start_offset, internal::SubstringMatcher<std::wstring>{find_this}, + str, start_offset, internal::MakeSubstringMatcher(find_this), replace_with, internal::ReplaceType::REPLACE_FIRST); } @@ -110,7 +110,7 @@ WStringPiece find_this, WStringPiece replace_with) { internal::DoReplaceMatchesAfterOffset( - str, start_offset, internal::SubstringMatcher<std::wstring>{find_this}, + str, start_offset, internal::MakeSubstringMatcher(find_this), replace_with, internal::ReplaceType::REPLACE_ALL); }
diff --git a/base/strings/sys_string_conversions_mac.mm b/base/strings/sys_string_conversions_mac.mm index 5fb45f6..f8d0f4ba 100644 --- a/base/strings/sys_string_conversions_mac.mm +++ b/base/strings/sys_string_conversions_mac.mm
@@ -95,9 +95,9 @@ // Given a StringPiece |in| with an encoding specified by |in_encoding|, return // it as a CFStringRef. Returns NULL on failure. -template <typename StringType> +template <typename CharT> static ScopedCFTypeRef<CFStringRef> StringPieceToCFStringWithEncodingsT( - BasicStringPiece<StringType> in, + BasicStringPiece<CharT> in, CFStringEncoding in_encoding) { const auto in_length = in.length(); if (in_length == 0) @@ -105,8 +105,7 @@ return ScopedCFTypeRef<CFStringRef>(CFStringCreateWithBytes( kCFAllocatorDefault, reinterpret_cast<const UInt8*>(in.data()), - in_length * sizeof(typename BasicStringPiece<StringType>::value_type), - in_encoding, false)); + in_length * sizeof(CharT), in_encoding, false)); } // Specify the byte ordering explicitly, otherwise CFString will be confused
diff --git a/base/test/data/mac/arm64 b/base/test/data/mac/arm64 deleted file mode 100755 index abab59a..0000000 --- a/base/test/data/mac/arm64 +++ /dev/null Binary files differ
diff --git a/base/test/data/mac/elf b/base/test/data/mac/elf deleted file mode 100755 index 613db40c..0000000 --- a/base/test/data/mac/elf +++ /dev/null Binary files differ
diff --git a/base/test/data/mac/print_arch.c b/base/test/data/mac/print_arch.c deleted file mode 100644 index 848869b9..0000000 --- a/base/test/data/mac/print_arch.c +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2020 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. - -// Mac: -// clang -Os -isysroot $(xcrun -show-sdk-path) -mmacosx-version-min=10.10 \ -// -arch x86_64 print_arch.c -o x86_64 -Wl,-s -Wl,-dead_strip -// clang -Os -isysroot $(xcrun -show-sdk-path) -mmacosx-version-min=11.0 \ -// -arch arm64 print_arch.c -o arm64 -Wl,-s -Wl,-dead_strip -// lipo -create x86_64 arm64 -o universal -// clang -Os -isysroot /apple/sdk/MacOSX10.13.sdk -mmacosx-version-min=10.10 \ -// -arch i386 print_arch.c -o x86 -Wl,-s -Wl,-dead_strip -// -// Linux: -// gcc -Os -fuse-ld=gold print_arch.c -o elf -s \ -// -ffunction-sections -fdata-sections -Wl,--gc-sections - -#include <stdio.h> -#include <stdlib.h> - -int main(int argc, char* argv[]) { -#if defined(__i386__) - static const char kArchitecture[] = "x86"; -#elif defined(__x86_64__) - static const char kArchitecture[] = "x86_64"; -#elif defined(__arm64__) || defined(__aarch64__) - static const char kArchitecture[] = "arm64"; -#endif - - printf("%s\n", kArchitecture); - - return EXIT_SUCCESS; -}
diff --git a/base/test/data/mac/universal b/base/test/data/mac/universal deleted file mode 100755 index 3dd89d7..0000000 --- a/base/test/data/mac/universal +++ /dev/null Binary files differ
diff --git a/base/test/data/mac/x86 b/base/test/data/mac/x86 deleted file mode 100755 index 9a73f62..0000000 --- a/base/test/data/mac/x86 +++ /dev/null Binary files differ
diff --git a/base/test/data/mac/x86_64 b/base/test/data/mac/x86_64 deleted file mode 100755 index 06183fc..0000000 --- a/base/test/data/mac/x86_64 +++ /dev/null Binary files differ
diff --git a/base/test/test_mock_time_task_runner.cc b/base/test/test_mock_time_task_runner.cc index b1f0196..09f449f 100644 --- a/base/test/test_mock_time_task_runner.cc +++ b/base/test/test_mock_time_task_runner.cc
@@ -188,7 +188,7 @@ DCHECK_GE(delta, TimeDelta()); const TimeTicks original_now_ticks = NowTicks(); - ProcessAllTasksNoLaterThan(delta); + ProcessTasksNoLaterThan(delta); ForwardClocksUntilTickTime(original_now_ticks + delta); } @@ -203,12 +203,17 @@ void TestMockTimeTaskRunner::RunUntilIdle() { DCHECK(thread_checker_.CalledOnValidThread()); - ProcessAllTasksNoLaterThan(TimeDelta()); + ProcessTasksNoLaterThan(TimeDelta()); +} + +void TestMockTimeTaskRunner::ProcessNextNTasks(int n) { + DCHECK(thread_checker_.CalledOnValidThread()); + ProcessTasksNoLaterThan(TimeDelta::Max(), n); } void TestMockTimeTaskRunner::FastForwardUntilNoTasksRemain() { DCHECK(thread_checker_.CalledOnValidThread()); - ProcessAllTasksNoLaterThan(TimeDelta::Max()); + ProcessTasksNoLaterThan(TimeDelta::Max()); } void TestMockTimeTaskRunner::ClearPendingTasks() { @@ -338,7 +343,8 @@ // Empty default implementation. } -void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) { +void TestMockTimeTaskRunner::ProcessTasksNoLaterThan(TimeDelta max_delta, + int limit) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_GE(max_delta, TimeDelta()); @@ -351,7 +357,7 @@ } const TimeTicks original_now_ticks = NowTicks(); - while (!quit_run_loop_) { + for (int i = 0; !quit_run_loop_ && (limit < 0 || i < limit); i++) { OnBeforeSelectingTask(); TestPendingTask task_info; if (!DequeueNextTask(original_now_ticks, max_delta, &task_info))
diff --git a/base/test/test_mock_time_task_runner.h b/base/test/test_mock_time_task_runner.h index dbf075f..acc83a3 100644 --- a/base/test/test_mock_time_task_runner.h +++ b/base/test/test_mock_time_task_runner.h
@@ -165,6 +165,13 @@ // elapse. void RunUntilIdle(); + // Processes the next |n| pending tasks in the order that they would normally + // be processed advancing the virtual time as needed. Cancelled tasks are not + // run but they still count towards |n|. If |n| is negative, this is + // equivalent to FastForwardUntilNoTasksRemain(). If we run out of pending + // tasks before reaching |n|, we early out. + void ProcessNextNTasks(int n); + // Clears the queue of pending tasks without running them. void ClearPendingTasks(); @@ -248,10 +255,13 @@ TemporalOrder> TaskPriorityQueue; // Core of the implementation for all flavors of fast-forward methods. Given a - // non-negative |max_delta|, runs all tasks with a remaining delay less than - // or equal to |max_delta|, and moves virtual time forward as needed for each - // processed task. Pass in TimeDelta::Max() as |max_delta| to run all tasks. - void ProcessAllTasksNoLaterThan(TimeDelta max_delta); + // non-negative |max_delta|, processes up to |limit| tasks with a remaining + // delay less than or equal to |max_delta|, and moves virtual time forward as + // needed for each processed task. Cancelled tasks count towards |limit|. If + // |limit| is negative, no limit on the number of processed tasks is imposed. + // Pass in TimeDelta::Max() as |max_delta| and a negative |limit| to run all + // tasks. + void ProcessTasksNoLaterThan(TimeDelta max_delta, int limit = -1); // Forwards |now_ticks_| until it equals |later_ticks|, and forwards |now_| by // the same amount. Calls OnAfterTimePassed() if |later_ticks| > |now_ticks_|.
diff --git a/base/test/test_mock_time_task_runner_unittest.cc b/base/test/test_mock_time_task_runner_unittest.cc index 4b47bdf..1fff6c3 100644 --- a/base/test/test_mock_time_task_runner_unittest.cc +++ b/base/test/test_mock_time_task_runner_unittest.cc
@@ -295,4 +295,66 @@ EXPECT_EQ(2u, task_runner->GetPendingTaskCount()); } +TEST(TestMockTimeTaskRunnerTest, ProcessNextNTasks) { + auto mock_time_task_runner = MakeRefCounted<TestMockTimeTaskRunner>( + TestMockTimeTaskRunner::Type::kStandalone); + int counter = 0; + + mock_time_task_runner->PostTask( + FROM_HERE, base::BindOnce([](int* counter) { *counter += 1; }, + Unretained(&counter))); + mock_time_task_runner->PostTask( + FROM_HERE, base::BindOnce([](int* counter) { *counter += 32; }, + Unretained(&counter))); + + CancelableOnceClosure task1(base::BindOnce( + [](int* counter) { *counter += 16; }, Unretained(&counter))); + mock_time_task_runner->PostTask(FROM_HERE, task1.callback()); + + mock_time_task_runner->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 256; }, + Unretained(&counter)), + TimeDelta::FromSeconds(3)); + mock_time_task_runner->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 64; }, + Unretained(&counter)), + TimeDelta::FromSeconds(1)); + mock_time_task_runner->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 1024; }, + Unretained(&counter)), + TimeDelta::FromMinutes(20)); + mock_time_task_runner->PostDelayedTask( + FROM_HERE, + base::BindOnce([](int* counter) { *counter += 4096; }, + Unretained(&counter)), + TimeDelta::FromDays(20)); + task1.Cancel(); + + int expected_value = 0; + EXPECT_EQ(expected_value, counter); + mock_time_task_runner->ProcessNextNTasks(0); + EXPECT_EQ(expected_value, counter); + + mock_time_task_runner->ProcessNextNTasks(2); + expected_value += 1; + expected_value += 32; + EXPECT_EQ(expected_value, counter); + + // The next task was canceled, so |counter| shouldn't change. + mock_time_task_runner->ProcessNextNTasks(1); + EXPECT_EQ(expected_value, counter); + + mock_time_task_runner->ProcessNextNTasks(1); + expected_value += 64; + EXPECT_EQ(expected_value, counter); + + mock_time_task_runner->ProcessNextNTasks(-1); + expected_value += 256; + expected_value += 1024; + expected_value += 4096; + EXPECT_EQ(expected_value, counter); +} } // namespace base
diff --git a/build/android/gyp/proguard.py b/build/android/gyp/proguard.py index fd7f6ba..46c93f0 100755 --- a/build/android/gyp/proguard.py +++ b/build/android/gyp/proguard.py
@@ -31,6 +31,7 @@ (28, 'P'), (29, 'Q'), (30, 'R'), + (31, 'S'), ]
diff --git a/build/android/list_java_targets.py b/build/android/list_java_targets.py index cd123c1..d0689a6e 100755 --- a/build/android/list_java_targets.py +++ b/build/android/list_java_targets.py
@@ -98,16 +98,20 @@ def ninja_build_config_target(self): return self.ninja_target + '__build_config_crbug_908819' + @property + def build_config_path(self): + """Returns the filepath of the project's .build_config.""" + ninja_target = self.ninja_target + # Support targets at the root level. e.g. //:foo + if ninja_target[0] == ':': + ninja_target = ninja_target[1:] + subpath = ninja_target.replace(':', os.path.sep) + '.build_config' + return os.path.join(constants.GetOutDirectory(), 'gen', subpath) + def build_config(self): """Reads and returns the project's .build_config JSON.""" if not self._build_config: - ninja_target = self.ninja_target - # Support targets at the root level. e.g. //:foo - if ninja_target[0] == ':': - ninja_target = ninja_target[1:] - subpath = ninja_target.replace(':', os.path.sep) + '.build_config' - path = os.path.join('gen', subpath) - with open(os.path.join(constants.GetOutDirectory(), path)) as jsonfile: + with open(self.build_config_path) as jsonfile: self._build_config = json.load(jsonfile) return self._build_config @@ -141,6 +145,9 @@ parser.add_argument('--print-types', action='store_true', help='Print type of each target') + parser.add_argument('--print-build-config-paths', + action='store_true', + help='Print path to the .build_config of each target') parser.add_argument('--build', action='store_true', help='Build all .build_config files.') @@ -199,6 +206,8 @@ if args.print_types: to_print = f'{to_print}: {e.get_type()}' + elif args.print_build_config_paths: + to_print = f'{to_print}: {e.build_config_path}' print(to_print)
diff --git a/build/android/pylib/gtest/gtest_test_instance.py b/build/android/pylib/gtest/gtest_test_instance.py index 30d4a39f..294e2db 100644 --- a/build/android/pylib/gtest/gtest_test_instance.py +++ b/build/android/pylib/gtest/gtest_test_instance.py
@@ -175,10 +175,15 @@ def handle_possibly_unknown_test(): if test_name is not None: - results.append(base_test_result.BaseTestResult( - TestNameWithoutDisabledPrefix(test_name), - fallback_result_type or base_test_result.ResultType.UNKNOWN, - duration, log=symbolize_stack_and_merge_with_log())) + results.append( + base_test_result.BaseTestResult( + TestNameWithoutDisabledPrefix(test_name), + # If we get here, that means we started a test, but it did not + # produce a definitive test status output, so assume it crashed. + # crbug/1191716 + fallback_result_type or base_test_result.ResultType.CRASH, + duration, + log=symbolize_stack_and_merge_with_log())) for l in output: matcher = _RE_TEST_STATUS.match(l)
diff --git a/build/android/pylib/gtest/gtest_test_instance_test.py b/build/android/pylib/gtest/gtest_test_instance_test.py index ccbd7fd..f3e85d0 100755 --- a/build/android/pylib/gtest/gtest_test_instance_test.py +++ b/build/android/pylib/gtest/gtest_test_instance_test.py
@@ -156,7 +156,7 @@ self.assertEquals(1, len(actual)) self.assertEquals('FooTest.Bar', actual[0].GetName()) self.assertEquals(0, actual[0].GetDuration()) - self.assertEquals(base_test_result.ResultType.UNKNOWN, actual[0].GetType()) + self.assertEquals(base_test_result.ResultType.CRASH, actual[0].GetType()) def testParseGTestOutput_nonterminalUnknown(self): raw_output = [ @@ -169,7 +169,7 @@ self.assertEquals('FooTest.Bar', actual[0].GetName()) self.assertEquals(0, actual[0].GetDuration()) - self.assertEquals(base_test_result.ResultType.UNKNOWN, actual[0].GetType()) + self.assertEquals(base_test_result.ResultType.CRASH, actual[0].GetType()) self.assertEquals('FooTest.Baz', actual[1].GetName()) self.assertEquals(1, actual[1].GetDuration())
diff --git a/cc/document_transition/document_transition_request.cc b/cc/document_transition/document_transition_request.cc index 0509feec5..408d111 100644 --- a/cc/document_transition/document_transition_request.cc +++ b/cc/document_transition/document_transition_request.cc
@@ -67,13 +67,11 @@ // static std::unique_ptr<DocumentTransitionRequest> DocumentTransitionRequest::CreatePrepare(Effect effect, - base::TimeDelta duration, uint32_t document_tag, uint32_t shared_element_count, base::OnceClosure commit_callback) { return base::WrapUnique(new DocumentTransitionRequest( - effect, duration, document_tag, shared_element_count, - std::move(commit_callback))); + effect, document_tag, shared_element_count, std::move(commit_callback))); } // static @@ -87,13 +85,11 @@ DocumentTransitionRequest::DocumentTransitionRequest( Effect effect, - base::TimeDelta duration, uint32_t document_tag, uint32_t shared_element_count, base::OnceClosure commit_callback) : type_(Type::kSave), effect_(effect), - duration_(duration), document_tag_(document_tag), shared_element_count_(shared_element_count), commit_callback_(std::move(commit_callback)), @@ -116,13 +112,6 @@ const std::map<DocumentTransitionSharedElementId, viz::CompositorRenderPassId>& shared_element_render_pass_id_map) const { - // Note that the clamped_duration is also verified at - // CompositorFrameTransitionDirective deserialization time. - auto clamped_duration = - duration_ < viz::CompositorFrameTransitionDirective::kMaxDuration - ? duration_ - : viz::CompositorFrameTransitionDirective::kMaxDuration; - std::vector<viz::CompositorRenderPassId> shared_passes(shared_element_count_); for (uint32_t i = 0; i < shared_passes.size(); ++i) { auto it = shared_element_render_pass_id_map.find( @@ -131,15 +120,14 @@ continue; shared_passes[i] = it->second; } - return viz::CompositorFrameTransitionDirective( - sequence_id_, type_, effect_, clamped_duration, std::move(shared_passes)); + return viz::CompositorFrameTransitionDirective(sequence_id_, type_, effect_, + std::move(shared_passes)); } std::string DocumentTransitionRequest::ToString() const { std::ostringstream str; str << "[type: " << TypeToString(type_) << " effect: " << EffectToString(effect_) - << " duration: " << duration_.InMillisecondsF() << "ms" << " sequence_id: " << sequence_id_ << "]"; return str.str(); }
diff --git a/cc/document_transition/document_transition_request.h b/cc/document_transition/document_transition_request.h index cf3fbf1..2f2ecdd 100644 --- a/cc/document_transition/document_transition_request.h +++ b/cc/document_transition/document_transition_request.h
@@ -28,7 +28,6 @@ // Creates a Type::kPrepare type of request. static std::unique_ptr<DocumentTransitionRequest> CreatePrepare( Effect effect, - base::TimeDelta duration, uint32_t document_tag, uint32_t shared_element_count, base::OnceClosure commit_callback); @@ -70,7 +69,6 @@ using Type = viz::CompositorFrameTransitionDirective::Type; DocumentTransitionRequest(Effect effect, - base::TimeDelta duration, uint32_t document_tag, uint32_t shared_element_count, base::OnceClosure commit_callback); @@ -80,7 +78,6 @@ const Type type_; const Effect effect_ = Effect::kNone; - const base::TimeDelta duration_; const uint32_t document_tag_; const uint32_t shared_element_count_; base::OnceClosure commit_callback_;
diff --git a/cc/document_transition/document_transition_request_unittest.cc b/cc/document_transition/document_transition_request_unittest.cc index 4b073cd..bd68656 100644 --- a/cc/document_transition/document_transition_request_unittest.cc +++ b/cc/document_transition/document_transition_request_unittest.cc
@@ -17,7 +17,7 @@ auto request = DocumentTransitionRequest::CreatePrepare( DocumentTransitionRequest::Effect::kRevealLeft, - base::TimeDelta::FromMilliseconds(123), /*document_tag=*/0, + /*document_tag=*/0, /*shared_element_count=*/0, std::move(callback)); EXPECT_FALSE(called); @@ -28,33 +28,15 @@ auto directive = request->ConstructDirective({}); EXPECT_GT(directive.sequence_id(), 0u); EXPECT_EQ(DocumentTransitionRequest::Effect::kRevealLeft, directive.effect()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(123), directive.duration()); EXPECT_EQ(viz::CompositorFrameTransitionDirective::Type::kSave, directive.type()); auto duplicate = request->ConstructDirective({}); EXPECT_EQ(duplicate.sequence_id(), directive.sequence_id()); EXPECT_EQ(duplicate.effect(), directive.effect()); - EXPECT_EQ(duplicate.duration(), directive.duration()); EXPECT_EQ(duplicate.type(), directive.type()); } -TEST(DocumentTransitionRequestTest, PrepareRequestLongDurationIsCapped) { - auto long_duration = base::TimeDelta::FromSeconds(1); - - ASSERT_GT(long_duration, - viz::CompositorFrameTransitionDirective::kMaxDuration); - - auto request = DocumentTransitionRequest::CreatePrepare( - DocumentTransitionRequest::Effect::kRevealLeft, long_duration, - /*document_tag=*/0, /*shared_element_transition=*/0, - base::OnceCallback<void()>()); - - auto directive = request->ConstructDirective({}); - EXPECT_EQ(viz::CompositorFrameTransitionDirective::kMaxDuration, - directive.duration()); -} - TEST(DocumentTransitionRequestTest, StartRequest) { bool called = false; auto callback = base::BindLambdaForTesting([&called]() { called = true; });
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index fa640dd..c5776b2 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -9464,7 +9464,6 @@ layer_tree_host()->AddDocumentTransitionRequest( DocumentTransitionRequest::CreatePrepare( DocumentTransitionRequest::Effect::kExplode, - base::TimeDelta::FromMilliseconds(123), /*document_tag=*/0, /*shared_element_count=*/0, base::BindLambdaForTesting([this]() { CommitLambdaCalled(); }))); layer_tree_host()->AddDocumentTransitionRequest( @@ -9485,7 +9484,6 @@ viz::CompositorFrameTransitionDirective::Type::kSave); EXPECT_EQ(save.effect(), viz::CompositorFrameTransitionDirective::Effect::kExplode); - EXPECT_EQ(save.duration(), base::TimeDelta::FromMilliseconds(123)); const auto& animate = frame.metadata.transition_directives[1]; EXPECT_GT(animate.sequence_id(), save.sequence_id());
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 442f908..edc143e8 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -3528,6 +3528,7 @@ "java/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManagerImpl.java", "java/src/org/chromium/chrome/browser/push_messaging/PushMessagingServiceObserver.java", "java/src/org/chromium/chrome/browser/query_tiles/TileProviderFactory.java", + "java/src/org/chromium/chrome/browser/query_tiles/TileServiceUtils.java", "java/src/org/chromium/chrome/browser/read_later/ReadingListBridge.java", "java/src/org/chromium/chrome/browser/resources/ResourceMapper.java", "java/src/org/chromium/chrome/browser/rlz/RevenueStats.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index e624e4b..287f7b9 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1148,6 +1148,7 @@ "java/src/org/chromium/chrome/browser/query_tiles/QueryTileSection.java", "java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java", "java/src/org/chromium/chrome/browser/query_tiles/TileProviderFactory.java", + "java/src/org/chromium/chrome/browser/query_tiles/TileServiceUtils.java", "java/src/org/chromium/chrome/browser/read_later/ReadLaterIPHController.java", "java/src/org/chromium/chrome/browser/read_later/ReadingListBridge.java", "java/src/org/chromium/chrome/browser/read_later/ReadingListUtils.java",
diff --git a/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected b/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected index 6e4bafb..d9803351 100644 --- a/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected +++ b/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected
@@ -928,3 +928,13 @@ -keepclassmembers,allowobfuscation class ** { @org.chromium.base.annotations.VerifiesOnR <methods>; } +-keep @interface org.chromium.base.annotations.VerifiesOnS +-if @org.chromium.base.annotations.VerifiesOnS class * { + *** *(...); +} +-keep,allowobfuscation class <1> { + *** <2>(...); +} +-keepclassmembers,allowobfuscation class ** { + @org.chromium.base.annotations.VerifiesOnS <methods>; +}
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java index 2b1bc962..0a31268 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -397,8 +397,7 @@ Assert.assertTrue(CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START)); Assert.assertTrue(ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(-1)); - CriteriaHelper.pollUiThread( - mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); + waitForOverviewVisible(); Assert.assertFalse(LibraryLoader.getInstance().isInitialized()); assertThat(mActivityTestRule.getActivity().getLayoutManager()) @@ -427,8 +426,7 @@ Assert.assertEquals("single", StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue()); Assert.assertTrue(ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(-1)); - CriteriaHelper.pollUiThread( - mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); + waitForOverviewVisible(); Assert.assertFalse(LibraryLoader.getInstance().isInitialized()); assertThat(mActivityTestRule.getActivity().getLayoutManager()) @@ -475,8 +473,7 @@ Assert.assertEquals("single", StartSurfaceConfiguration.START_SURFACE_VARIATION.getValue()); Assert.assertTrue(ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(-1)); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); Assert.assertFalse(LibraryLoader.getInstance().isInitialized()); TopToolbarCoordinator topToolbarCoordinator = @@ -594,8 +591,7 @@ public void renderTabSwitcher_NoStateFile() throws IOException { // clang-format on startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); + waitForOverviewVisible(); mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "tabSwitcher_empty"); } @@ -614,8 +610,7 @@ // clang-format on createCorruptedTabStateFile(); startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); + waitForOverviewVisible(); mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view), "tabSwitcher_empty"); } @@ -659,8 +654,7 @@ // Must be after createTabStateFile() to read these files. startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); + waitForOverviewVisible(); RecyclerView recyclerView = mActivityTestRule.getActivity().findViewById(R.id.tab_list_view); CriteriaHelper.pollUiThread(() -> allCardsHaveThumbnail(recyclerView)); @@ -707,8 +701,7 @@ // Must be after createTabStateFile() to read these files. startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); + waitForOverviewVisible(); RecyclerView recyclerView = mActivityTestRule.getActivity().findViewById(R.id.tab_list_view); CriteriaHelper.pollUiThread(() -> allCardsHaveThumbnail(recyclerView)); @@ -767,8 +760,7 @@ TabAttributeCache.setTitleForTesting(0, "Google"); startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); View surface = mActivityTestRule.getActivity().findViewById(R.id.primary_tasks_surface_view); @@ -992,8 +984,7 @@ public void renderSingleAsHomepage_NoTab_ScrollToolbarToTop() throws IOException { // clang-format on startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); // Initializes native. startAndWaitNativeInitialization(); @@ -1041,15 +1032,13 @@ public void testShadowVisibility() { // clang-format on startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); onView(withId(R.id.toolbar_shadow)) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); startAndWaitNativeInitialization(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); onView(withId(R.id.toolbar_shadow)) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); @@ -1071,8 +1060,7 @@ onViewWaiting(withId(R.id.toolbar_shadow)).check(matches(isDisplayed())); startAndWaitNativeInitialization(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); onView(withId(R.id.toolbar_shadow)) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); @@ -1095,8 +1083,7 @@ TabAttributeCache.setTitleForTesting(0, "Google"); startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); // Initializes native. startAndWaitNativeInitialization(); @@ -1133,8 +1120,7 @@ mSuggestionsDeps.getFactory().mostVisitedSites = mostVisitedSites; startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); // Initializes native. startAndWaitNativeInitialization(); @@ -1155,33 +1141,6 @@ } @Test - @SmallTest - @Feature({"RenderTest"}) - @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) - // clang-format off - @EnableFeatures({ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<Study,", - ChromeFeatureList.START_SURFACE_ANDROID + "<Study"}) - @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION, - "force-fieldtrials=Study/Group", - IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/single"+ - "/exclude_mv_tiles/false"}) - public void renderSingleAsHomepage_MVTiles() throws IOException, InterruptedException { - // clang-format on - saveSiteSuggestionTilesToFile(); - startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); - - View surface = - mActivityTestRule.getActivity().findViewById(R.id.primary_tasks_surface_view); - - ViewUtils.onViewWaiting( - allOf(withId(R.id.tile_view_title), withText("0 EXPLORE_SITES"), isDisplayed())); - ChromeRenderTestRule.sanitize(surface); - mRenderTestRule.render(surface, "singlePane_MV_withExploreSitesView"); - } - - @Test @MediumTest @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) // clang-format off @@ -1198,8 +1157,7 @@ public void testSingleAsHomepage_Landscape_TabSize() throws IOException{ // clang-format on startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); // Initializes native. startAndWaitNativeInitialization(); @@ -1249,7 +1207,8 @@ } @Test - @SmallTest + @MediumTest + @Feature({"RenderTest"}) @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) // clang-format off @EnableFeatures({ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<Study,", @@ -1258,7 +1217,7 @@ "force-fieldtrials=Study/Group", IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/single/exclude_mv_tiles/false"}) - public void testExploreTopSites() throws InterruptedException { + public void testMVTilesWithExploreSitesView() throws InterruptedException, IOException { // clang-format on // When showing MV tiles pre-native, explore top sites view is already rendered with a // non-null icon. This test is for ensuring explore top sites view is built and clickable @@ -1270,8 +1229,15 @@ mSuggestionsDeps.getFactory().mostVisitedSites = mostVisitedSites; startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); + + View surface = + mActivityTestRule.getActivity().findViewById(R.id.primary_tasks_surface_view); + + ViewUtils.onViewWaiting( + allOf(withId(R.id.tile_view_title), withText("0 EXPLORE_SITES"), isDisplayed())); + ChromeRenderTestRule.sanitize(surface); + mRenderTestRule.render(surface, "singlePane_MV_withExploreSitesView"); // Initializes native. startAndWaitNativeInitialization(); @@ -1322,11 +1288,9 @@ // clang-format on createTabStateFile(new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, null, 5); startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - mActivityTestRule.getActivity().getLayoutManager()::overviewVisible); + waitForOverviewVisible(); startAndWaitNativeInitialization(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); // Note that onView(R.id.more_tabs).perform(click()) can not be used since it requires 90 // percent of the view's area is displayed to the users. However, this view has negative @@ -1383,8 +1347,7 @@ TabAttributeCache.setTitleForTesting(0, "Google"); startMainActivityFromLauncher(); - CriteriaHelper.pollUiThread( - () -> mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); + waitForOverviewVisible(); ViewUtils.onViewWaiting(withId(R.id.tab_list_view)); Assert.assertEquals(1, PseudoTab.getAllPseudoTabsFromStateFile().size()); } @@ -1518,4 +1481,12 @@ // Wait util the file has been saved. latch.await(); } + + private void waitForOverviewVisible() { + CriteriaHelper.pollUiThread( + () + -> mActivityTestRule.getActivity().getLayoutManager() != null + && mActivityTestRule.getActivity().getLayoutManager().overviewVisible(), + MAX_TIMEOUT_MS, CriteriaHelper.DEFAULT_POLLING_INTERVAL); + } }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java index 12959981d..763ad90 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -1973,7 +1973,7 @@ public void testNewSurfaceFromHomeButton(){ // clang-format on assumeTrue(mImmediateReturn); - onViewWaiting(withId(R.id.feed_stream_recycler_view)); + waitForOverviewVisible(); onViewWaiting( allOf(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container), isDisplayed())); onViewWaiting(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)); @@ -1992,8 +1992,8 @@ pressHomePageButton(); // MV tiles and carousel tab switcher should not show anymore. + waitForOverviewVisible(); onViewWaiting(withId(R.id.start_tab_switcher_button)); - onViewWaiting(withId(R.id.feed_stream_recycler_view)); onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container)) .check(matches(withEffectiveVisibility(GONE))); onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)) @@ -2009,7 +2009,7 @@ public void testNewSurfaceHideTabOnlyFromHomeButton(){ // clang-format on assumeTrue(mImmediateReturn); - onViewWaiting(withId(R.id.feed_stream_recycler_view)); + waitForOverviewVisible(); onViewWaiting(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container)); onViewWaiting(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)); onViewWaiting(withId(R.id.start_tab_switcher_button)); @@ -2027,7 +2027,7 @@ pressHomePageButton(); // MV tiles should shown and carousel tab switcher should not show anymore. - onViewWaiting(withId(R.id.feed_stream_recycler_view)); + waitForOverviewVisible(); onViewWaiting(withId(R.id.start_tab_switcher_button)); onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container)) .check(matches(withEffectiveVisibility(VISIBLE)));
diff --git a/chrome/android/java/res_app/layout/main.xml b/chrome/android/java/res_app/layout/main.xml index e1ebeb6..519d22f 100644 --- a/chrome/android/java/res_app/layout/main.xml +++ b/chrome/android/java/res_app/layout/main.xml
@@ -143,4 +143,12 @@ android:layout_height="0px" android:layout_gravity="bottom" /> + <FrameLayout + android:id="@+id/survey_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:visibility="gone" + android:clipChildren="false"/> + </merge>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java index 158559c..c72d5f2e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
@@ -352,4 +352,8 @@ public boolean canStartForegroundServiceWhileInvisible() { return true; } + + public String getDefaultQueryTilesServerUrl() { + return ""; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index e200db6f..3c86f5e1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -8,6 +8,7 @@ import org.chromium.base.annotations.RemovableInRelease; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; +import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.firstrun.FirstRunUtils; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.CachedFieldTrialParameter; @@ -159,9 +160,16 @@ * won't be tagged with their corresponding field trial experiments. */ public void cacheMinimalBrowserFlags() { + CachedFeatureFlags.cacheMinimalBrowserFlagsTimeFromNativeTime(); + // TODO(crbug.com/995355): Move other related flags from cacheNativeFlags() to here. - CachedFeatureFlags.cacheNativeFlags( - Arrays.asList(ChromeFeatureList.SERVICE_MANAGER_FOR_DOWNLOAD, - ChromeFeatureList.SERVICE_MANAGER_FOR_BACKGROUND_PREFETCH)); + CachedFeatureFlags.cacheNativeFlags(Arrays.asList(ChromeFeatureList.EXPERIMENTS_FOR_AGSA, + ChromeFeatureList.SERVICE_MANAGER_FOR_DOWNLOAD, + ChromeFeatureList.SERVICE_MANAGER_FOR_BACKGROUND_PREFETCH)); + + // This is used by CustomTabsConnection implementation, which does not necessarily start + // chrome. + CachedFeatureFlags.cacheFieldTrialParameters( + Arrays.asList(CustomTabActivity.EXPERIMENTS_FOR_AGSA_PARAMS)); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java index 7c7bf6e8..479206d8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java
@@ -333,7 +333,7 @@ OverlayViewDelegate delegate = new OverlayViewDelegate(cv); mWebContents.initialize(ChromeVersionInfo.getProductVersion(), delegate, cv, mActivity.getWindowAndroid(), WebContents.createDefaultInternalsHolder()); - ContentUtils.setUserAgentOverride(mWebContents); + ContentUtils.setUserAgentOverride(mWebContents, /* overrideInNewTabs= */ false); // Transfers the ownership of the WebContents to the native OverlayPanelContent. OverlayPanelContentJni.get().setWebContents(mNativeOverlayPanelContentPtr,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelCoordinator.java index d576774..ccbf7bd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelCoordinator.java
@@ -87,7 +87,7 @@ ViewAndroidDelegate.createBasicDelegate(mWebContentView); mWebContents.initialize(ChromeVersionInfo.getProductVersion(), delegate, mWebContentView, mWindowAndroid, WebContents.createDefaultInternalsHolder()); - ContentUtils.setUserAgentOverride(mWebContents); + ContentUtils.setUserAgentOverride(mWebContents, /* overrideInNewTabs= */ false); } private void destroyWebContents() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java index dbcd170..3e3c9f1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java
@@ -226,7 +226,7 @@ mWebContents.initialize(ChromeVersionInfo.getProductVersion(), ViewAndroidDelegate.createBasicDelegate(mContentView), mContentView, mWindow, WebContents.createDefaultInternalsHolder()); - ContentUtils.setUserAgentOverride(mWebContents); + ContentUtils.setUserAgentOverride(mWebContents, /* overrideInNewTabs= */ false); } private void destroyWebContents() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/content/ContentUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/content/ContentUtils.java index 07c8e4b..a66560bc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/content/ContentUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/content/ContentUtils.java
@@ -24,13 +24,13 @@ * for "Request desktop site". Set it for WebContents so that it is available * when a NavigationEntry requires the user agent to be overridden. */ - public static void setUserAgentOverride(WebContents webContents) { - ContentUtilsJni.get().setUserAgentOverride(webContents); + public static void setUserAgentOverride(WebContents webContents, boolean overrideInNewTabs) { + ContentUtilsJni.get().setUserAgentOverride(webContents, overrideInNewTabs); } @NativeMethods interface Natives { String getBrowserUserAgent(); - void setUserAgentOverride(WebContents webContents); + void setUserAgentOverride(WebContents webContents, boolean overrideInNewTabs); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 26b2f74..ed3c6f0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -39,6 +39,8 @@ import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider; import org.chromium.chrome.browser.customtabs.features.CustomTabNavigationBarController; import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; +import org.chromium.chrome.browser.flags.AllCachedFieldTrialParameters; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.fonts.FontPreloader; import org.chromium.chrome.browser.infobar.InfoBarContainer; import org.chromium.chrome.browser.night_mode.NightModeStateProvider; @@ -58,6 +60,12 @@ private final CustomTabsConnection mConnection = CustomTabsConnection.getInstance(); + /** + * Contains all the parameters of the EXPERIMENTS_FOR_AGSA feature. + */ + public static final AllCachedFieldTrialParameters EXPERIMENTS_FOR_AGSA_PARAMS = + new AllCachedFieldTrialParameters(ChromeFeatureList.EXPERIMENTS_FOR_AGSA); + private CustomTabActivityTabProvider.Observer mTabChangeObserver = new CustomTabActivityTabProvider.Observer() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/TileServiceUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/TileServiceUtils.java new file mode 100644 index 0000000..5079f8e --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/TileServiceUtils.java
@@ -0,0 +1,21 @@ +// 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.query_tiles; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.browser.AppHooks; + +/** + * Class for providing helper method for corresponding native class. + */ +public class TileServiceUtils { + /** + * @return Default server URL for getting query tiles. + */ + @CalledByNative + private static String getDefaultServerUrl() { + return AppHooks.get().getDefaultQueryTilesServerUrl(); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index ced637c..03a5e45 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -540,6 +540,7 @@ return true; } + switchUserAgentIfNeeded(); restoreIfNeeded(); return true; } @@ -1376,7 +1377,9 @@ } mWebContents.setImportance(mImportance); - ContentUtils.setUserAgentOverride(mWebContents); + + ContentUtils.setUserAgentOverride(mWebContents, + calculateUserAgentOverrideOption() == UserAgentOverrideOption.TRUE); mContentView.addOnAttachStateChangeListener(mAttachStateChangeListener); updateInteractableState(); @@ -1678,7 +1681,10 @@ } private void switchUserAgentIfNeeded() { - if (calculateUserAgentOverrideOption() == UserAgentOverrideOption.INHERIT) return; + if (calculateUserAgentOverrideOption() == UserAgentOverrideOption.INHERIT + || getWebContents() == null) { + return; + } boolean usingDesktopUserAgent = getWebContents().getNavigationController().getUseDesktopUserAgent(); TabUtils.switchUserAgent(this, /* switchToDesktop */ !usingDesktopUserAgent,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java index f5ccb52..9d23da6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -66,6 +66,7 @@ import org.chromium.chrome.browser.toolbar.ToolbarButtonInProductHelpController; import org.chromium.chrome.browser.toolbar.ToolbarIntentMetadata; import org.chromium.chrome.browser.ui.RootUiCoordinator; +import org.chromium.chrome.browser.ui.TabObscuringHandler; import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; import org.chromium.chrome.browser.ui.default_browser_promo.DefaultBrowserPromoUtils; import org.chromium.chrome.browser.ui.tablet.emptybackground.EmptyBackgroundViewWrapper; @@ -107,6 +108,7 @@ private ActivityTabTabObserver mTabObserver; private ContinuousSearchContainerCoordinator mContinuousSearchContainerCoordinator; private Callback<Integer> mContinuousSearchObserver; + private TabObscuringHandler.Observer mContinuousSearchTabObscuringHandlerObserver; private int mStatusIndicatorHeight; private int mContinuousSearchHeight; @@ -202,10 +204,12 @@ } if (mContinuousSearchContainerCoordinator != null) { + getTabObscuringHandler().removeObserver(mContinuousSearchTabObscuringHandlerObserver); mContinuousSearchContainerCoordinator.removeHeightObserver(mContinuousSearchObserver); mContinuousSearchContainerCoordinator.destroy(); mContinuousSearchContainerCoordinator = null; mContinuousSearchObserver = null; + mContinuousSearchTabObscuringHandlerObserver = null; } super.destroy(); } @@ -507,6 +511,9 @@ updateTopControlsHeight(); }; mContinuousSearchContainerCoordinator.addHeightObserver(mContinuousSearchObserver); + mContinuousSearchTabObscuringHandlerObserver = + isObscured -> mContinuousSearchContainerCoordinator.updateTabObscured(isObscured); + getTabObscuringHandler().addObserver(mContinuousSearchTabObscuringHandlerObserver); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java index 41c7c09..ff31c21 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java
@@ -6,6 +6,7 @@ import android.app.Activity; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; import android.net.Uri; import android.provider.Browser; @@ -13,13 +14,12 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.ServiceTabLauncher; -import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton; +import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.multiwindow.MultiInstanceManager; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; @@ -55,13 +55,11 @@ private static Activity getActivityForTabId(int id) { if (id == Tab.INVALID_TAB_ID) return null; - for (Activity runningActivity : ApplicationStatus.getRunningActivities()) { - if (!(runningActivity instanceof ChromeActivity)) continue; + Tab tab = TabWindowManagerSingleton.getInstance().getTabById(id); + if (tab == null) return null; - ChromeActivity activity = (ChromeActivity) runningActivity; - if (activity.getTabModelSelector().getTabById(id) != null) return activity; - } - return null; + Context tabContext = tab.getContext(); + return (tabContext instanceof Activity) ? (Activity) tabContext : null; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java index 6f368a435..5cea5ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java
@@ -188,7 +188,10 @@ } boolean isToolbarOnScreenTop() { - return mPropertyModel.get(IS_VISIBLE) && mPropertyModel.get(TRANSLATION_Y) == 0; + return (mOverviewModeState == StartSurfaceState.SHOWN_HOMEPAGE + || mOverviewModeState == StartSurfaceState.SHOWN_TABSWITCHER) + && !mPropertyModel.get(IS_INCOGNITO) && mPropertyModel.get(IS_VISIBLE) + && mPropertyModel.get(TRANSLATION_Y) == 0; } void setOnNewTabClickHandler(View.OnClickListener listener) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index e60e1e8..bfdcc6a78 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -48,6 +48,7 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.compositor.layouts.StaticLayout; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.layouts.animation.CompositorAnimationHandler; import org.chromium.chrome.browser.tab.EmptyTabObserver; @@ -68,6 +69,7 @@ import org.chromium.chrome.test.util.MenuUtils; import org.chromium.chrome.test.util.NewTabPageTestUtils; import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.components.javascript_dialogs.JavascriptTabModalDialog; @@ -82,6 +84,7 @@ import org.chromium.content_public.browser.test.util.UiUtils; import org.chromium.content_public.common.ContentSwitches; import org.chromium.net.test.EmbeddedTestServer; +import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.modaldialog.ModalDialogProperties; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.test.util.UiRestriction; @@ -205,6 +208,180 @@ }); } + /** + * Verify that a popup will use desktop user agent on tablets, and use mobile user agent on + * phones. + * Mobile user agent header sample: + * "Mozilla/5.0 (Linux; Android 11; Pixel 2 XL) AppleWebKit/537.36 (KHTML, like Gecko) + * Chrome/91.0.4451.0 Mobile Safari/537.36" + * Desktop user agent header sample: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 + * (KHTML, like Gecko) Chrome/91.0.4451.0 Safari/537.36" + */ + @Test + @LargeTest + @Feature({"Navigation"}) + @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) + @EnableFeatures({ChromeFeatureList.REQUEST_DESKTOP_SITE_FOR_TABLETS + "<Study"}) + @CommandLineFlags.Add({ContentSwitches.DISABLE_POPUP_BLOCKING, "force-fieldtrials=Study/Group", + "force-fieldtrial-params=Study.Group:screen_width_dp/100/enabled/true"}) + public void + testPopupLoadDesktopSiteOnTablet() throws InterruptedException { + mTestServer = new EmbeddedTestServer(); + mTestServer.initializeNative(InstrumentationRegistry.getContext(), + EmbeddedTestServer.ServerHTTPSSetting.USE_HTTP); + mTestServer.addDefaultHandlers(""); + Assert.assertTrue(mTestServer.start()); + + mActivityTestRule.loadUrl(mTestServer.getURL("/echoheader?User-Agent")); + final Tab tab = mActivityTestRule.getActivity().getActivityTab(); + String echoHeader = getTabBodyText(tab); + // Tab should request desktop sites on tablets, mobile sites on phone. + if (DeviceFormFactor.isTablet()) { + Assert.assertTrue("Tab should request desktop sites for tablets.", + tab.getWebContents().getNavigationController().getUseDesktopUserAgent()); + Assert.assertFalse( + "On tablets, User-Agent in the header should not contain Android, but it is : " + + echoHeader, + echoHeader.contains("Android")); + } else { + Assert.assertFalse("Tab should request mobile sites for phones.", + tab.getWebContents().getNavigationController().getUseDesktopUserAgent()); + Assert.assertTrue( + "On phones, User-Agent in the header should contain Android, but it is : " + + echoHeader, + echoHeader.contains("Android")); + } + + // Open a popup window from the first tab. + TestThreadUtils.runOnUiThreadBlocking( + () + -> tab.getWebContents().evaluateJavaScriptForTests("(function() {" + + " window.open('/echoheader?User-Agent');" + + "})()", + null)); + + CriteriaHelper.pollUiThread(() -> { + int tabCount = mActivityTestRule.getActivity() + .getTabModelSelector() + .getModel(false) + .getCount(); + Criteria.checkThat(tabCount, Matchers.is(2)); + final Tab currentTab = mActivityTestRule.getActivity().getActivityTab(); + + // Make sure that the new tab have desktop user agent on tablets, and mobile user agent + // on phones. + Criteria.checkThat(currentTab.getId(), Matchers.not(tab.getId())); + Criteria.checkThat( + currentTab.getWebContents().getNavigationController().getUseDesktopUserAgent(), + Matchers.is(DeviceFormFactor.isTablet())); + }); + + Tab currentTab = mActivityTestRule.getActivity().getActivityTab(); + echoHeader = getTabBodyText(tab); + if (DeviceFormFactor.isTablet()) { + Assert.assertFalse( + "On tablets, User-Agent in the header should not contain Android, but it is : " + + echoHeader, + echoHeader.contains("Android")); + } else { + Assert.assertTrue( + "On phones, User-Agent in the header should contain Android, but it is : " + + echoHeader, + echoHeader.contains("Android")); + } + } + + /** + * Verify that a client redirect popup will use desktop user agent on tablets, and use mobile + * user agent on phones. The key difference from testPopupLoadDesktopSiteOnTablet is, this test + * is using target='_blank' in the link. + * Mobile user agent header sample: "Mozilla/5.0 (Linux; Android 11; Pixel + * 2 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4451.0 Mobile Safari/537.36" + * Desktop user agent header sample: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 + * (KHTML, like Gecko) Chrome/91.0.4451.0 Safari/537.36" + */ + @Test + @LargeTest + @Feature({"Navigation"}) + @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) + @EnableFeatures({ChromeFeatureList.REQUEST_DESKTOP_SITE_FOR_TABLETS + "<Study"}) + @CommandLineFlags.Add({ContentSwitches.DISABLE_POPUP_BLOCKING, "force-fieldtrials=Study/Group", + "force-fieldtrial-params=Study.Group:screen_width_dp/100/enabled/true"}) + public void + testRedirectTargetBlankPopupLoadDesktopSiteOnTablet() throws Exception { + mTestServer = new EmbeddedTestServer(); + mTestServer.initializeNative(InstrumentationRegistry.getContext(), + EmbeddedTestServer.ServerHTTPSSetting.USE_HTTP); + mTestServer.addDefaultHandlers(""); + Assert.assertTrue(mTestServer.start()); + + String echoHeaderUrl = mTestServer.getURL("/echoheader?User-Agent"); + mActivityTestRule.loadUrl(echoHeaderUrl); + final Tab tab = mActivityTestRule.getActivity().getActivityTab(); + String echoHeader = getTabBodyText(tab); + // Tab should request desktop sites on tablets, mobile sites on phone. + if (DeviceFormFactor.isTablet()) { + Assert.assertTrue("Tab should request desktop sites for tablets.", + tab.getWebContents().getNavigationController().getUseDesktopUserAgent()); + Assert.assertFalse( + "On tablets, User-Agent in the header should not contain Android, but it is : " + + echoHeader, + echoHeader.contains("Android")); + } else { + Assert.assertFalse("Tab should request mobile sites for phones.", + tab.getWebContents().getNavigationController().getUseDesktopUserAgent()); + Assert.assertTrue( + "On phones, User-Agent in the header should contain Android, but it is : " + + echoHeader, + echoHeader.contains("Android")); + } + + // Open a popup window from the first tab. + String redirectToEchoHeaderUrl = mTestServer.getURL("/client-redirect?" + echoHeaderUrl); + + // Add a redirect link with target='_blank' and click it. + mActivityTestRule.runJavaScriptCodeInCurrentTab( + String.format("var aTag = document.createElement('a');" + + "aTag.id = '%s';" + + "aTag.setAttribute('href','%s');" + + "aTag.setAttribute('target','_blank');" + + "aTag.innerHTML = 'Click Me!';" + + "document.body.appendChild(aTag);", + "target_blank_id", redirectToEchoHeaderUrl)); + DOMUtils.clickNode(mActivityTestRule.getActivity().getActivityTab().getWebContents(), + "target_blank_id"); + + CriteriaHelper.pollUiThread(() -> { + int tabCount = mActivityTestRule.getActivity() + .getTabModelSelector() + .getModel(false) + .getCount(); + Criteria.checkThat(tabCount, Matchers.is(2)); + final Tab currentTab = mActivityTestRule.getActivity().getActivityTab(); + + // Make sure that the new tab have desktop user agent on tablets, and mobile user agent + // on phones. + Criteria.checkThat(currentTab.getId(), Matchers.not(tab.getId())); + Criteria.checkThat( + currentTab.getWebContents().getNavigationController().getUseDesktopUserAgent(), + Matchers.is(DeviceFormFactor.isTablet())); + }); + + Tab currentTab = mActivityTestRule.getActivity().getActivityTab(); + echoHeader = getTabBodyText(tab); + if (DeviceFormFactor.isTablet()) { + Assert.assertFalse( + "On tablets, User-Agent in the header should not contain Android, but it is : " + + echoHeader, + echoHeader.contains("Android")); + } else { + Assert.assertTrue( + "On phones, User-Agent in the header should contain Android, but it is : " + + echoHeader, + echoHeader.contains("Android")); + } + } + @Test @MediumTest public void testAlertDialogDoesNotChangeActiveModel() { @@ -1104,4 +1281,14 @@ return dialogModel != null ? dialogModel.get(ModalDialogProperties.CONTROLLER) : null; }); } + + private String getTabBodyText(Tab tab) { + try { + return JavaScriptUtils.executeJavaScriptAndWaitForResult( + tab.getWebContents(), "document.body.innerText"); + } catch (Exception ex) { + assert false : "Unexpected Exception"; + } + return null; + } }
diff --git a/chrome/app/chrome_crash_reporter_client.cc b/chrome/app/chrome_crash_reporter_client.cc index abacf22..cd9a053d 100644 --- a/chrome/app/chrome_crash_reporter_client.cc +++ b/chrome/app/chrome_crash_reporter_client.cc
@@ -128,7 +128,7 @@ GetProductNameAndVersion(&c_product_name, &c_version); *product_name = c_product_name; *version = c_version; - *channel = chrome::GetChannelName(); + *channel = chrome::GetChannelName(chrome::WithExtendedStable(true)); } base::FilePath ChromeCrashReporterClient::GetReporterLogFilename() {
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 66e9bd1..11eef011 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1709,6 +1709,9 @@ <message name="IDS_NETWORK_LIST_ITEM_DOWNLOAD" desc="Text for the button displayed for pending eSIM profiles that installs the profile when pressed."> Download </message> + <message name="IDS_NETWORK_LIST_ITEM_DOWNLOAD_A11Y_LABEL" desc="A11Y label for the button displayed for pending eSIM profiles that installs the profile when pressed. Includes profile name"> + Download, <ph name="PROFILE_NAME">$1<ex>Cellular</ex></ph> + </message> <message name="IDS_NETWORK_LIST_ITEM_UNLOCK" desc="Text for the button displayed for locked cellular networks that opens a dialog to unlock the network when pressed "> Unlock </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_NETWORK_LIST_ITEM_DOWNLOAD_A11Y_LABEL.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_NETWORK_LIST_ITEM_DOWNLOAD_A11Y_LABEL.png.sha1 new file mode 100644 index 0000000..8d14164 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_NETWORK_LIST_ITEM_DOWNLOAD_A11Y_LABEL.png.sha1
@@ -0,0 +1 @@ +3d20fb65a8739b6f27689cb727c958e5d03a9d03 \ No newline at end of file
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index de642281..b6fb5b6 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -1213,22 +1213,6 @@ </message> </if> - <!-- Rosetta installation for protected media --> - <if expr="is_macosx"> - <message name="IDS_ROSETTA_INSTALL_TITLE" - desc="Title of the 'do you want to install Rosetta' dialog. Used when there is a page title."> - To enable Chromium to play protected media, you need to install Rosetta. Do you want to install it now? - </message> - <message name="IDS_ROSETTA_INSTALL_BODY" - desc="Body text of the 'do you want to install Rosetta' dialog."> - Rosetta enables Chromium to play the protected media on this page. - </message> - <message name="IDS_ROSETTA_INSTALL_RESTART_DIALOG" - desc="Title text of the dialog once Rosetta is installed."> - To use Rosetta to play protected media, you must restart Chromium. - </message> - </if> - <!-- Strings for full restore notifications --> <if expr="chromeos"> <message name="IDS_RESTORE_NOTIFICATION_DISPLAY_SOURCE" desc="This is the string shown as the display source of the notification for the user to select restore or not on startup.">
diff --git a/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_BODY.png.sha1 b/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_BODY.png.sha1 deleted file mode 100644 index 6433fc3..0000000 --- a/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_BODY.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -106a2358b6eec402ec016d40cafdc7d78d0196c3 \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG.png.sha1 b/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG.png.sha1 deleted file mode 100644 index 21a9bb64..0000000 --- a/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -1a3093c65a8df9d7e6627216ccef82caf3fdaa9f \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_TITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_TITLE.png.sha1 deleted file mode 100644 index 6433fc3..0000000 --- a/chrome/app/chromium_strings_grd/IDS_ROSETTA_INSTALL_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -106a2358b6eec402ec016d40cafdc7d78d0196c3 \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 670cc8aa..2c6108f 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5575,6 +5575,12 @@ <message name="IDS_NTP_CUSTOMIZE_COLOR_PICKER_LABEL" desc="The label for the color picker in the customization menu on the New Tab Page"> Custom color </message> + <message name="IDS_NTP_THEME_MANAGED_DIALOG_TITLE" desc="Title text for the dialog informing users that their theme is managed when they try selecting a theme on the New Tab Page."> + Theme is set by your Organization + </message> + <message name="IDS_NTP_THEME_MANAGED_DIALOG_BODY" desc="Body text for the dialog informing users that their theme is managed when they try selecting a theme on the New Tab Page."> + Your administrator has set a default theme which cannot be changed. + </message> <message name="IDS_NTP_CUSTOMIZE_DEFAULT_LABEL" desc="The label for the Default theme in the customization menu on the New Tab Page"> Default color </message> @@ -11185,30 +11191,6 @@ </message> </if> - <if expr="is_macosx"> - <!-- The Rosetta is required infobar --> - <message name="IDS_ROSETTA_REQUIRED_INFOBAR_TEXT" - desc="The infobar text when installation of Rosetta is required"> - To play protected media on this page, you need to install Rosetta. - </message> - <message name="IDS_ROSETTA_REQUIRED_INFOBAR_LINK_TEXT" - desc="The learn more text when installation of Rosetta is required."> - Learn more - </message> - <message name="IDS_ROSETTA_REQUIRED_INFOBAR_BUTTON_TEXT" - desc="The button text when installation of Rosetta is required."> - Install Rosetta - </message> - <message name="IDS_ROSETTA_INSTALL_RESTART_DIALOG_NOW" - desc="The 'restart now' button in the dialog once Rosetta is installed."> - Restart Now - </message> - <message name="IDS_ROSETTA_INSTALL_RESTART_DIALOG_LATER" - desc="The 'restart later' button in the dialog once Rosetta is installed."> - Restart Later - </message> - </if> - <message name="IDS_NAME_WINDOW_PROMPT_TITLE" desc="Title of the prompt to choose a new name for a window."> Name this window
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_THEME_MANAGED_DIALOG_BODY.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_THEME_MANAGED_DIALOG_BODY.png.sha1 new file mode 100644 index 0000000..782770dd --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_NTP_THEME_MANAGED_DIALOG_BODY.png.sha1
@@ -0,0 +1 @@ +39c3d1efadcca98e74579f408a64ef60f5bc5378 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_THEME_MANAGED_DIALOG_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_THEME_MANAGED_DIALOG_TITLE.png.sha1 new file mode 100644 index 0000000..852753b --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_NTP_THEME_MANAGED_DIALOG_TITLE.png.sha1
@@ -0,0 +1 @@ +94610316284f5922ee7947634f7f2974e3d7bf88 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG_LATER.png.sha1 b/chrome/app/generated_resources_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG_LATER.png.sha1 deleted file mode 100644 index 21a9bb64..0000000 --- a/chrome/app/generated_resources_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG_LATER.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -1a3093c65a8df9d7e6627216ccef82caf3fdaa9f \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG_NOW.png.sha1 b/chrome/app/generated_resources_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG_NOW.png.sha1 deleted file mode 100644 index 21a9bb64..0000000 --- a/chrome/app/generated_resources_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG_NOW.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -1a3093c65a8df9d7e6627216ccef82caf3fdaa9f \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_BUTTON_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_BUTTON_TEXT.png.sha1 deleted file mode 100644 index 792d43be..0000000 --- a/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_BUTTON_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -843a5130d3bf16400915f89eb55839c6ff32a6df \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_LINK_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_LINK_TEXT.png.sha1 deleted file mode 100644 index 792d43be..0000000 --- a/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_LINK_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -843a5130d3bf16400915f89eb55839c6ff32a6df \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_TEXT.png.sha1 deleted file mode 100644 index 792d43be..0000000 --- a/chrome/app/generated_resources_grd/IDS_ROSETTA_REQUIRED_INFOBAR_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -843a5130d3bf16400915f89eb55839c6ff32a6df \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index ec5f2a1..6f54bf5 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -1230,22 +1230,6 @@ </message> </if> - <!-- Rosetta installation for protected media --> - <if expr="is_macosx"> - <message name="IDS_ROSETTA_INSTALL_TITLE" - desc="Title of the 'do you want to install Rosetta' dialog. Used when there is a page title."> - To enable Chrome to play protected media, you need to install Rosetta. Do you want to install it now? - </message> - <message name="IDS_ROSETTA_INSTALL_BODY" - desc="Body text of the 'do you want to install Rosetta' dialog."> - Rosetta enables Chrome to play the protected media on this page. - </message> - <message name="IDS_ROSETTA_INSTALL_RESTART_DIALOG" - desc="Title text of the dialog once Rosetta is installed."> - To use Rosetta to play protected media, you must restart Chrome. - </message> - </if> - <!-- Strings for full restore notifications --> <if expr="chromeos"> <message name="IDS_RESTORE_NOTIFICATION_DISPLAY_SOURCE" desc="This is the string shown as the display source of the notification for the user to select restore or not on startup.">
diff --git a/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_BODY.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_BODY.png.sha1 deleted file mode 100644 index 6433fc3..0000000 --- a/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_BODY.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -106a2358b6eec402ec016d40cafdc7d78d0196c3 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG.png.sha1 deleted file mode 100644 index 21a9bb64..0000000 --- a/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_RESTART_DIALOG.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -1a3093c65a8df9d7e6627216ccef82caf3fdaa9f \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_TITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_TITLE.png.sha1 deleted file mode 100644 index 6433fc3..0000000 --- a/chrome/app/google_chrome_strings_grd/IDS_ROSETTA_INSTALL_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -106a2358b6eec402ec016d40cafdc7d78d0196c3 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 5aa7bcf19..df4c37b 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -1023,6 +1023,9 @@ <message name="IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_KEYBOARD_SPEED_LABEL" desc="Label for slider which sets the time interval for Switch Access to automatically scan to the next element while navigating in the keyboard. Switch Access is an alternative input method designed for users with limited mobility, where the user has as little as one switch (for example, a button) to control the computer."> Keyboard scanning speed </message> + <message name="IDS_SETTINGS_SWITCH_ACCESS_POINT_SCAN_SPEED_LABEL" desc="Label for slider which sets the speed of point scanning cursors for Switch Access, which move across the screen, allowing the user to choose a precise point to click. Switch Access is an alternative input method designed for users with limited mobility, where the user has as little as one switch (for example, a button) to control the computer."> + Point scanning speed + </message> <message name="IDS_SETTINGS_DURATION_IN_SECONDS" desc="A duration in seconds. Should be short."> <ph name="DURATION">$1<ex>1.5</ex></ph>s </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_SWITCH_ACCESS_POINT_SCAN_SPEED_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_SWITCH_ACCESS_POINT_SCAN_SPEED_LABEL.png.sha1 new file mode 100644 index 0000000..24325c9 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_SWITCH_ACCESS_POINT_SCAN_SPEED_LABEL.png.sha1
@@ -0,0 +1 @@ +0ad8ecb305601f366ca04ada45279a412258f1bc \ No newline at end of file
diff --git a/chrome/app/shared_settings_strings.grdp b/chrome/app/shared_settings_strings.grdp index c8f25b4..8a5fb699 100644 --- a/chrome/app/shared_settings_strings.grdp +++ b/chrome/app/shared_settings_strings.grdp
@@ -19,8 +19,8 @@ <message name="IDS_SETTINGS_CAPTIONS_PREFERENCES_SUBTITLE" desc="Section subtitle for Caption preferences. Disclaimer that not all apps and sites support the system caption style. Some apps and sites don't use the web captioning standard and have their own captioning platform."> Customize caption size and style for apps and sites that support this setting </message> - <message name="IDS_SETTINGS_CAPTIONS_TEXT_SIZE" desc="Name of the caption text size preference. Text size will apply to captions and alo Live Caption when it's enabled."> - Text size (Also applies to Live Caption) + <message name="IDS_SETTINGS_CAPTIONS_TEXT_SIZE" desc="Name of the caption text size preference."> + Text size </message> <message name="IDS_SETTINGS_CAPTIONS_TEXT_FONT" desc="Name of the caption text font preference."> Text font
diff --git a/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_CAPTIONS_TEXT_SIZE.png.sha1 b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_CAPTIONS_TEXT_SIZE.png.sha1 index 54a9aa01..d503480 100644 --- a/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_CAPTIONS_TEXT_SIZE.png.sha1 +++ b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_CAPTIONS_TEXT_SIZE.png.sha1
@@ -1 +1 @@ -cf655ed8640962529a2e35740866a51673a2dab4 \ No newline at end of file +b55864b352c16de204787498ba0452aab72c6171 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 6289c725..c951cb3 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4119,6 +4119,8 @@ "themes/custom_theme_supplier.h", "themes/increased_contrast_theme_supplier.cc", "themes/increased_contrast_theme_supplier.h", + "themes/theme_color_policy_handler.cc", + "themes/theme_color_policy_handler.h", "themes/theme_helper.cc", "themes/theme_helper.h", "themes/theme_properties.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index a65a786..d6b9de8d 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2470,7 +2470,6 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) constexpr char kAssistantBetterOnboardingInternalName[] = "enable-assistant-better-onboarding"; -constexpr char kAssistantTimersV2InternalName[] = "enable-assistant-timers-v2"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if defined(OS_LINUX) || defined(OS_CHROMEOS) @@ -2736,6 +2735,9 @@ {"colr-v1-fonts", flag_descriptions::kCOLRV1FontsName, flag_descriptions::kCOLRV1FontsDescription, kOsAll, FEATURE_VALUE_TYPE(blink::features::kCOLRV1Fonts)}, + {"enable-container-queries", flag_descriptions::kCSSContainerQueriesName, + flag_descriptions::kCSSContainerQueriesDescription, kOsAll, + FEATURE_VALUE_TYPE(blink::features::kCSSContainerQueries)}, #if defined(OS_ANDROID) {"contextual-search-debug", flag_descriptions::kContextualSearchDebugName, flag_descriptions::kContextualSearchDebugDescription, kOsAndroid, @@ -5339,11 +5341,6 @@ flag_descriptions::kEnableAssistantBetterOnboardingDescription, kOsCrOS, FEATURE_VALUE_TYPE( chromeos::assistant::features::kAssistantBetterOnboarding)}, - - {kAssistantTimersV2InternalName, - flag_descriptions::kEnableAssistantTimersV2Name, - flag_descriptions::kEnableAssistantTimersV2Description, kOsCrOS, - FEATURE_VALUE_TYPE(chromeos::assistant::features::kAssistantTimersV2)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ @@ -7192,6 +7189,12 @@ {"composite-after-paint", flag_descriptions::kCompositeAfterPaintName, flag_descriptions::kCompositeAfterPaintDescription, kOsAll, FEATURE_VALUE_TYPE(blink::features::kCompositeAfterPaint)}, + {"autofill-parse-merchant-promo-code-fields", + flag_descriptions::kAutofillParseMerchantPromoCodeFieldsName, + flag_descriptions::kAutofillParseMerchantPromoCodeFieldsDescription, + kOsAll, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillParseMerchantPromoCodeFields)}, // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag @@ -7260,8 +7263,7 @@ } // The following flags are only available to teamfooders. - if (!strcmp(kAssistantBetterOnboardingInternalName, entry.internal_name) || - !strcmp(kAssistantTimersV2InternalName, entry.internal_name)) { + if (!strcmp(kAssistantBetterOnboardingInternalName, entry.internal_name)) { return !base::FeatureList::IsEnabled(features::kTeamfoodFlags); }
diff --git a/chrome/browser/android/content/content_utils.cc b/chrome/browser/android/content/content_utils.cc index 3bbc7446..dec37d4 100644 --- a/chrome/browser/android/content/content_utils.cc +++ b/chrome/browser/android/content/content_utils.cc
@@ -16,9 +16,11 @@ static void JNI_ContentUtils_SetUserAgentOverride( JNIEnv* env, - const base::android::JavaParamRef<jobject>& jweb_contents) { + const base::android::JavaParamRef<jobject>& jweb_contents, + jboolean j_override_in_new_tabs) { content::WebContents* web_contents = content::WebContents::FromJavaWebContents(jweb_contents); embedder_support::SetDesktopUserAgentOverride( - web_contents, embedder_support::GetUserAgentMetadata()); + web_contents, embedder_support::GetUserAgentMetadata(), + j_override_in_new_tabs); }
diff --git a/chrome/browser/ash/notifications/deprecation_notification_controller.cc b/chrome/browser/ash/notifications/deprecation_notification_controller.cc index 43fa4cd..690efff 100644 --- a/chrome/browser/ash/notifications/deprecation_notification_controller.cc +++ b/chrome/browser/ash/notifications/deprecation_notification_controller.cc
@@ -52,6 +52,19 @@ return true; } +bool DeprecationNotificationController::NotifyDeprecatedFKeyRewrite() { + if (fkey_notification_shown_) { + return false; + } + + const std::string id = std::string(kNotificationIdPrefix) + "fkey"; + ShowNotificationFromIdWithLauncherKey(id, IDS_ASH_SHORTCUT_DEPRECATION_FKEY); + + // Don't show the notification again. + fkey_notification_shown_ = true; + return true; +} + bool DeprecationNotificationController::NotifyDeprecatedAltBasedKeyRewrite( ui::KeyboardCode key_code) { if (!ShouldShowAltBasedDeprecationNotification(key_code)) { @@ -73,6 +86,7 @@ void DeprecationNotificationController::ResetStateForTesting() { shown_key_notifications_.clear(); right_click_notification_shown_ = false; + fkey_notification_shown_ = false; } void DeprecationNotificationController::ShowNotificationFromIdWithLauncherKey(
diff --git a/chrome/browser/ash/notifications/deprecation_notification_controller.h b/chrome/browser/ash/notifications/deprecation_notification_controller.h index a139356..a6b1a2d 100644 --- a/chrome/browser/ash/notifications/deprecation_notification_controller.h +++ b/chrome/browser/ash/notifications/deprecation_notification_controller.h
@@ -32,6 +32,11 @@ // will only be shown once per user session. bool NotifyDeprecatedRightClickRewrite(); + // Call to inform the notification controller that a Search + Digit + // key rewrite (eg. Search+Digit to F<digit>) was deprecated. The + // notification will only be shown once per user session. + bool NotifyDeprecatedFKeyRewrite(); + // Call to inform the notification controller that an Alt based // key rewrite (eg. Alt+Up -> PageUp) was deprecated. The key_code // is the key that would have been generated by the rewrite. The notification @@ -65,6 +70,9 @@ // Used to only show the right click notification once per user session. bool right_click_notification_shown_ = false; + // Used to only show the F-Key notification once per user session. + bool fkey_notification_shown_ = false; + // Used to only show the key rewrite notifications once per user session. base::flat_set<ui::KeyboardCode> shown_key_notifications_;
diff --git a/chrome/browser/ash/notifications/deprecation_notification_controller_unittest.cc b/chrome/browser/ash/notifications/deprecation_notification_controller_unittest.cc index 1b2084a..c9f212c 100644 --- a/chrome/browser/ash/notifications/deprecation_notification_controller_unittest.cc +++ b/chrome/browser/ash/notifications/deprecation_notification_controller_unittest.cc
@@ -59,4 +59,19 @@ EXPECT_EQ(message_center_.NotificationCount(), 0); } +// Only one notification is shown no matter which F-Key is triggered. +TEST_F(DeprecationNotificationControllerTest, NoDuplicateFKeyNotifications) { + // First F-Key generates a notification. + controller_.NotifyDeprecatedFKeyRewrite(); + EXPECT_EQ(message_center_.NotificationCount(), 1); + + // Clear the messages from the message center. + message_center_.RemoveAllNotifications( + /*by_user=*/false, message_center::FakeMessageCenter::RemoveType::ALL); + + // Subsequent times don't generate an additional notification. + controller_.NotifyDeprecatedFKeyRewrite(); + EXPECT_EQ(message_center_.NotificationCount(), 0); +} + } // namespace ash
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc index ca96c83..6acc428 100644 --- a/chrome/browser/autofill/form_structure_browsertest.cc +++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -31,6 +31,7 @@ #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/pattern_provider/pattern_configuration_parser.h" #include "components/autofill/core/common/autofill_features.h" +#include "components/autofill/core/common/autofill_payments_features.h" #include "components/autofill/core/common/unique_ids.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" @@ -185,7 +186,9 @@ // TODO(crbug.com/1150895) Remove once launched. features::kAutofillParsingPatternsLanguageDetection, // TODO(crbug/1165780): Remove once shared labels are launched. - features::kAutofillEnableSupportForParsingWithSharedLabels}, + features::kAutofillEnableSupportForParsingWithSharedLabels, + // TODO(crbug/1190334): Remove once launched. + features::kAutofillParseMerchantPromoCodeFields}, // Disabled {}); }
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index ef60f170..c52a0a6b 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -944,7 +944,8 @@ #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_OPENBSD) // Set the product channel for crash reports. if (!crash_reporter::IsCrashpadEnabled()) { - breakpad::SetChannelCrashKey(chrome::GetChannelName()); + breakpad::SetChannelCrashKey( + chrome::GetChannelName(chrome::WithExtendedStable(true))); } #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_OPENBSD)
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c02abedc..774140a 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2205,7 +2205,8 @@ if (client_info) switch_value = client_info->client_id; switch_value.push_back(','); - switch_value.append(chrome::GetChannelName()); + switch_value.append( + chrome::GetChannelName(chrome::WithExtendedStable(true))); command_line->AppendSwitchASCII(switches::kEnableCrashReporter, switch_value); }
diff --git a/chrome/browser/chromeos/events/event_rewriter_delegate_impl.cc b/chrome/browser/chromeos/events/event_rewriter_delegate_impl.cc index 5738630c..13cdd60 100644 --- a/chrome/browser/chromeos/events/event_rewriter_delegate_impl.cc +++ b/chrome/browser/chromeos/events/event_rewriter_delegate_impl.cc
@@ -122,6 +122,10 @@ return deprecation_controller_->NotifyDeprecatedRightClickRewrite(); } +bool EventRewriterDelegateImpl::NotifyDeprecatedFKeyRewrite() { + return deprecation_controller_->NotifyDeprecatedFKeyRewrite(); +} + bool EventRewriterDelegateImpl::NotifyDeprecatedAltBasedKeyRewrite( ui::KeyboardCode key_code) { return deprecation_controller_->NotifyDeprecatedAltBasedKeyRewrite(key_code);
diff --git a/chrome/browser/chromeos/events/event_rewriter_delegate_impl.h b/chrome/browser/chromeos/events/event_rewriter_delegate_impl.h index 36532e0..cea9134 100644 --- a/chrome/browser/chromeos/events/event_rewriter_delegate_impl.h +++ b/chrome/browser/chromeos/events/event_rewriter_delegate_impl.h
@@ -39,6 +39,7 @@ int flags) const override; bool IsSearchKeyAcceleratorReserved() const override; bool NotifyDeprecatedRightClickRewrite() override; + bool NotifyDeprecatedFKeyRewrite() override; bool NotifyDeprecatedAltBasedKeyRewrite(ui::KeyboardCode key_code) override; private:
diff --git a/chrome/browser/chromeos/events/event_rewriter_unittest.cc b/chrome/browser/chromeos/events/event_rewriter_unittest.cc index a9bf85c8..b263b39 100644 --- a/chrome/browser/chromeos/events/event_rewriter_unittest.cc +++ b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
@@ -1870,57 +1870,78 @@ scoped_feature_list_.InitAndEnableFeature( ::features::kImprovedKeyboardShortcuts); TestNonAppleNonCustomLayoutKeyboardVariants({ - // Search+Number should now have no effect. + // Search+Number should now have no effect but a notification will + // be shown the first time F1 to F10 is pressed. {ui::ET_KEY_PRESSED, {ui::VKEY_1, ui::DomCode::DIGIT1, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'1'>::Character}, {ui::VKEY_1, ui::DomCode::DIGIT1, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'1'>::Character}}, + ui::DomKey::Constant<'1'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_2, ui::DomCode::DIGIT2, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'2'>::Character}, {ui::VKEY_2, ui::DomCode::DIGIT2, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'2'>::Character}}, + ui::DomKey::Constant<'2'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_3, ui::DomCode::DIGIT3, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'3'>::Character}, {ui::VKEY_3, ui::DomCode::DIGIT3, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'3'>::Character}}, + ui::DomKey::Constant<'3'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_4, ui::DomCode::DIGIT4, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'4'>::Character}, {ui::VKEY_4, ui::DomCode::DIGIT4, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'4'>::Character}}, + ui::DomKey::Constant<'4'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_5, ui::DomCode::DIGIT5, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'5'>::Character}, {ui::VKEY_5, ui::DomCode::DIGIT5, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'5'>::Character}}, + ui::DomKey::Constant<'5'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_6, ui::DomCode::DIGIT6, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'6'>::Character}, {ui::VKEY_6, ui::DomCode::DIGIT6, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'6'>::Character}}, + ui::DomKey::Constant<'6'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_7, ui::DomCode::DIGIT7, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'7'>::Character}, {ui::VKEY_7, ui::DomCode::DIGIT7, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'7'>::Character}}, + ui::DomKey::Constant<'7'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_8, ui::DomCode::DIGIT8, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'8'>::Character}, {ui::VKEY_8, ui::DomCode::DIGIT8, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'8'>::Character}}, + ui::DomKey::Constant<'8'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_9, ui::DomCode::DIGIT9, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'9'>::Character}, {ui::VKEY_9, ui::DomCode::DIGIT9, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'9'>::Character}}, + ui::DomKey::Constant<'9'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_0, ui::DomCode::DIGIT0, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'0'>::Character}, {ui::VKEY_0, ui::DomCode::DIGIT0, ui::EF_COMMAND_DOWN, - ui::DomKey::Constant<'0'>::Character}}, + ui::DomKey::Constant<'0'>::Character}, + kKeyboardDeviceId, + /*triggers_notification=*/true}, {ui::ET_KEY_PRESSED, {ui::VKEY_OEM_MINUS, ui::DomCode::MINUS, ui::EF_COMMAND_DOWN, ui::DomKey::Constant<'-'>::Character},
diff --git a/chrome/browser/chromeos/hats/hats_config.cc b/chrome/browser/chromeos/hats/hats_config.cc index 9dd61fa..6c8f5ee 100644 --- a/chrome/browser/chromeos/hats/hats_config.cc +++ b/chrome/browser/chromeos/hats/hats_config.cc
@@ -10,7 +10,7 @@ namespace chromeos { namespace { -constexpr int kMinDaysThreshold = 1; +constexpr int kMinDaysThreshold = 0; // HaTS Onboarding Experience is immediate } HatsConfig::HatsConfig(const base::Feature& feature, @@ -31,4 +31,12 @@ prefs::kHatsSurveyCycleEndTimestamp, // hatsCycleEndTimestampPrefName }; +// Onboarding Experience Survey -- shown after completing the Onboarding Dialog +const HatsConfig kHatsOnboardingSurvey = { + ::features::kHappinessTrackingSystemOnboarding, // feature + base::TimeDelta::FromMinutes(30), // hatsNewDeviceThreshold + prefs::kHatsOnboardingDeviceIsSelected, // hatsIsSelectedPrefName + prefs::kHatsOnboardingSurveyCycleEndTs, // hatsCycleEndTimestampPrefName +}; + } // namespace chromeos
diff --git a/chrome/browser/chromeos/hats/hats_config.h b/chrome/browser/chromeos/hats/hats_config.h index 05599a3..c54492f2 100644 --- a/chrome/browser/chromeos/hats/hats_config.h +++ b/chrome/browser/chromeos/hats/hats_config.h
@@ -39,6 +39,7 @@ // CrOS HaTS configs are declared here and defined in hats_config.cc extern const HatsConfig kHatsGeneralSurvey; +extern const HatsConfig kHatsOnboardingSurvey; } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_HATS_HATS_CONFIG_H_
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_uploader.cc b/chrome/browser/chromeos/policy/extension_install_event_log_uploader.cc index 86c70375..98da63733 100644 --- a/chrome/browser/chromeos/policy/extension_install_event_log_uploader.cc +++ b/chrome/browser/chromeos/policy/extension_install_event_log_uploader.cc
@@ -7,7 +7,6 @@ #include <atomic> #include "base/bind.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" @@ -55,8 +54,8 @@ }, profile, std::move(complete_cb)); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - std::move(task)); + content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, + std::move(task)); }, profile); }
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index ddf4edd..fe5ea41 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -435,6 +435,12 @@ registry->RegisterBooleanPref(::prefs::kHatsDeviceIsSelected, false); + registry->RegisterInt64Pref(::prefs::kHatsOnboardingSurveyCycleEndTs, + base::Time().ToInternalValue()); + + registry->RegisterBooleanPref(::prefs::kHatsOnboardingDeviceIsSelected, + false); + registry->RegisterBooleanPref(::prefs::kPinUnlockFeatureNotificationShown, false); registry->RegisterBooleanPref(
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc index 671c708..9dac8914 100644 --- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc +++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -6,7 +6,6 @@ #include <stddef.h> #include <stdint.h> -#include <string.h> #include <memory> #include <string> @@ -15,7 +14,6 @@ #include "base/base_paths.h" #include "base/bind.h" -#include "base/check.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" @@ -23,7 +21,6 @@ #include "base/native_library.h" #include "base/path_service.h" #include "base/stl_util.h" -#include "base/strings/string_util.h" #include "base/task/thread_pool.h" #include "base/values.h" #include "build/build_config.h" @@ -45,11 +42,6 @@ #include "chrome/common/media/component_widevine_cdm_hint_file_linux.h" #endif -#if defined(OS_MAC) -#include "base/mac/mach_o.h" -#include "base/mac/rosetta.h" -#endif // OS_MAC - #if !BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) #error This file should only be compiled when Widevine CDM component is enabled #endif @@ -61,8 +53,6 @@ namespace { -static bool g_was_widevine_cdm_component_rejected_due_to_no_rosetta; - // CRX hash. The extension id is: oimompecagnajdejgnnjijobebaeigek. const uint8_t kWidevineSha2Hash[] = { 0xe8, 0xce, 0xcf, 0x42, 0x06, 0xd0, 0x93, 0x49, 0x6d, 0xd9, 0x89, @@ -117,9 +107,6 @@ void RegisterWidevineCdmWithChrome( const base::Version& cdm_version, const base::FilePath& cdm_path, -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - bool launch_x86_64, -#endif std::unique_ptr<base::DictionaryValue> manifest) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -136,9 +123,6 @@ content::CdmInfo cdm_info(kWidevineCdmDisplayName, kWidevineCdmGuid, cdm_version, cdm_path, kWidevineCdmFileSystemId, std::move(capability), kWidevineKeySystem, false); -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - cdm_info.launch_x86_64 = launch_x86_64; -#endif // OS_MAC && ARCH_CPU_ARM64 CdmRegistry::GetInstance()->RegisterCdm(cdm_info); } #endif // !defined(OS_LINUX) && !defined(OS_CHROMEOS) @@ -149,27 +133,6 @@ base::GetNativeLibraryName(kWidevineCdmLibraryName); base::FilePath cdm_path = cdm_platform_dir.AppendASCII(cdm_lib_name); -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - // If no Widevine CDM is present in the normal native arm64 location, look for - // one in the x86_64 location. Beware that the architecture embedded in the - // pathname does not necessarily indicate what architecture the Mach-O file at - // that path supports: an x86_64 library may be found in an arm64 location. A - // separate base::GetMachOArchitectures call must be made to determine the - // actual architecture. - // - // If there is no file at all in the native arm64 location, fall back to the - // x86_64 location. VerifyInstallation() and UpdateCdmPath() will do Rosetta - // checks before actually using it. - if (!base::PathExists(cdm_path) && - base::EndsWith(cdm_platform_dir.value(), kWidevineCdmArch)) { - cdm_platform_dir = base::FilePath( - cdm_platform_dir.value().substr( - 0, cdm_platform_dir.value().size() - strlen(kWidevineCdmArch)) + - "x64"); - cdm_path = cdm_platform_dir.AppendASCII(cdm_lib_name); - } -#endif // OS_MAC && ARCH_CPU_ARM64 - return cdm_path; } @@ -251,22 +214,6 @@ const base::FilePath& install_dir) const { base::FilePath cdm_path = GetCdmPathFromInstallDir(install_dir); -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - // Before committing to run an x86_64 version of Widevine under Rosetta, make - // sure that Rosetta is actually available. It’s not installed by default. - const base::MachOArchitectures architectures = - base::GetMachOArchitectures(cdm_path); - const bool launch_x86_64 = - (architectures & (base::MachOArchitectures::kX86_64 | - base::MachOArchitectures::kARM64)) == - base::MachOArchitectures::kX86_64; - if (launch_x86_64 && !base::mac::IsRosettaInstalled()) { - g_was_widevine_cdm_component_rejected_due_to_no_rosetta = true; - return false; - } - g_was_widevine_cdm_component_rejected_due_to_no_rosetta = false; -#endif // OS_MAC && ARCH_CPU_ARM64 - content::CdmCapability capability; return IsCdmManifestCompatibleWithChrome(manifest) && base::PathExists(cdm_path) && ParseCdmManifest(manifest, &capability); @@ -315,66 +262,10 @@ if (!UpdateWidevineCdmHintFile(cdm_install_dir)) PLOG(WARNING) << "Failed to update Widevine CDM hint path."; #else - base::FilePath cdm_path = GetCdmPathFromInstallDir(absolute_cdm_install_dir); - -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - // Detect the architecture of the chosen Widevine CDM. If it contains x86_64 - // code and no arm64 code, arrange to run it via Rosetta translation. - // Detection is necessary because the library may contain only x86_64 code - // even if loaded from an arm64 path. This isn’t likely for the bundled - // Widevine CDM, but can happen with a component-updated version. - const base::MachOArchitectures architectures = - base::GetMachOArchitectures(cdm_path); - const bool launch_x86_64 = - (architectures & (base::MachOArchitectures::kX86_64 | - base::MachOArchitectures::kARM64)) == - base::MachOArchitectures::kX86_64; - - // In order for this strategy to work, Rosetta must be installed. That should - // be guaranteed by VerifyInstallation succeeding. - if (launch_x86_64) { - DCHECK(base::mac::IsRosettaInstalled()); - - // To avoid a long delay (15 seconds observed is typical) when first loading - // the Widevine CDM under Rosetta, submit required modules for ahead-of-time - // translation. The necessary modules are: - // - the helper executable to launch, - // - the framework that contains the vast majority of the code, and - // - the Widevine CDM library itself. - // If Rosetta’s translation cache for these modules is already current, they - // will not be re-translated. If anything requires translation, it will - // still be time-consuming, but it’ll happen on a background thread without - // bothering the user, hopefully before the user needs to use them. If these - // modules are needed before the translation is complete, translation will - // at least have had a head start. - - std::vector<base::FilePath> rosetta_translate_paths; - base::FilePath helper_path; - if (base::PathService::Get(content::CHILD_PROCESS_EXE, &helper_path)) { - rosetta_translate_paths.push_back(helper_path); - } - - base::FilePath framework_path; - if (base::PathService::Get(base::FILE_MODULE, &framework_path)) { - rosetta_translate_paths.push_back(framework_path); - } - - rosetta_translate_paths.push_back(cdm_path); - - base::ThreadPool::PostTask( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce(base::IgnoreResult( - &base::mac::RequestRosettaAheadOfTimeTranslation), - std::move(rosetta_translate_paths))); - } -#endif // OS_MAC && ARCH_CPU_ARM64 - content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, - base::BindOnce(&RegisterWidevineCdmWithChrome, cdm_version, cdm_path, -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - launch_x86_64, -#endif // OS_MAC && ARCH_CPU_ARM64 + base::BindOnce(&RegisterWidevineCdmWithChrome, cdm_version, + GetCdmPathFromInstallDir(absolute_cdm_install_dir), std::move(manifest))); #endif } @@ -385,8 +276,4 @@ installer->Register(cus, base::OnceClosure()); } -bool WasWidevineCdmComponentRejectedDueToNoRosetta() { - return g_was_widevine_cdm_component_rejected_due_to_no_rosetta; -} - } // namespace component_updater
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.h b/chrome/browser/component_updater/widevine_cdm_component_installer.h index 1bc8252..a52decee 100644 --- a/chrome/browser/component_updater/widevine_cdm_component_installer.h +++ b/chrome/browser/component_updater/widevine_cdm_component_installer.h
@@ -18,8 +18,6 @@ // The first part is IO intensive so we do it asynchronously in the file thread. void RegisterWidevineCdmComponent(ComponentUpdateService* cus); -bool WasWidevineCdmComponentRejectedDueToNoRosetta(); - } // namespace component_updater #endif // CHROME_BROWSER_COMPONENT_UPDATER_WIDEVINE_CDM_COMPONENT_INSTALLER_H_
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerCoordinator.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerCoordinator.java index ef28991..b9573bc 100644 --- a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerCoordinator.java +++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerCoordinator.java
@@ -99,6 +99,10 @@ mContainerMediator.removeHeightObserver(observer); } + public void updateTabObscured(boolean isObscured) { + mContainerMediator.updateTabObscured(isObscured); + } + private void registerResource() { if (mResourceRegistered) return;
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerMediator.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerMediator.java index f51dc1e4..e3b185b 100644 --- a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerMediator.java +++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerMediator.java
@@ -30,6 +30,7 @@ private boolean mInitialized; private boolean mIsVisible; + private boolean mIsTabObscured; private int mJavaLayoutHeight; ContinuousSearchContainerMediator(BrowserControlsStateProvider browserControlsStateProvider, @@ -47,6 +48,16 @@ } /** + * Called when the obscurity state of the current Tab changes. + * @param isObscured Whether the tab is obscured. + */ + void updateTabObscured(boolean isObscured) { + mIsTabObscured = isObscured; + mModel.set(ContinuousSearchContainerProperties.ANDROID_VIEW_VISIBILITY, + !mIsTabObscured && mIsVisible ? View.VISIBLE : View.INVISIBLE); + } + + /** * Displays the container. This will increase the top controls height with an animation that * is controlled by cc and displays the container. */ @@ -118,18 +129,22 @@ // Only show the composited view when the UI is partly visible (mid transition) and native // can run animations. mModel.set(ContinuousSearchContainerProperties.COMPOSITED_VIEW_VISIBLE, - !uiFullyVisible && isUiVisible && mCanAnimateNativeBrowserControls.get()); + !mIsTabObscured + && (!uiFullyVisible && isUiVisible + && mCanAnimateNativeBrowserControls.get())); // If we're running the animations in native, the Android view should only be visible when // the container is fully shown. Otherwise, the Android view will be visible if it's within // screen boundaries. mModel.set(ContinuousSearchContainerProperties.ANDROID_VIEW_VISIBILITY, - !uiFullyVisible && isUiVisible && mCanAnimateNativeBrowserControls.get() - ? View.GONE - : ((isUiVisible && !mCanAnimateNativeBrowserControls.get()) - || uiFullyVisible - ? View.VISIBLE - : View.GONE)); + mIsTabObscured + ? View.INVISIBLE + : !uiFullyVisible && isUiVisible && mCanAnimateNativeBrowserControls.get() + ? View.GONE + : ((isUiVisible && !mCanAnimateNativeBrowserControls.get()) + || uiFullyVisible + ? View.VISIBLE + : View.GONE)); final boolean doneHiding = !isUiVisible && !mIsVisible; if (doneHiding) {
diff --git a/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerMediatorTest.java b/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerMediatorTest.java index e5a84ef..3166b42 100644 --- a/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerMediatorTest.java +++ b/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchContainerMediatorTest.java
@@ -235,6 +235,80 @@ mCurrentBrowserControlsObserver); } + /** + * Tests that the container is invisible when the tab is obscured. + */ + @Test + public void testTabObscured_whileShowing() { + triggerShow(); + + // Top controls are fully visible. + updateBrowserControlParamsAndAssertModel(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT, 0, true, 0, + DEFAULT_CONTAINER_HEIGHT, false, View.VISIBLE); + + mMediator.updateTabObscured(true); + Assert.assertTrue("Tab obscurity shouldn't change mMediator.mIsVisible.", + mMediator.isVisibleForTesting()); + Assert.assertFalse("Composited view should only be visible while animating.", + mModel.get(ContinuousSearchContainerProperties.COMPOSITED_VIEW_VISIBLE)); + Assert.assertEquals("Android view should be View.INVISIBLE when tab is obscured.", + View.INVISIBLE, + mModel.get(ContinuousSearchContainerProperties.ANDROID_VIEW_VISIBILITY)); + + mMediator.updateTabObscured(false); + Assert.assertTrue("Tab obscurity shouldn't change mMediator.mIsVisible.", + mMediator.isVisibleForTesting()); + Assert.assertFalse("Composited view should only be visible while animating.", + mModel.get(ContinuousSearchContainerProperties.COMPOSITED_VIEW_VISIBLE)); + Assert.assertEquals("Android view should be View.VISIBLE when tab is not obscured", + View.VISIBLE, + mModel.get(ContinuousSearchContainerProperties.ANDROID_VIEW_VISIBILITY)); + } + + /** + * Tests that the container is invisible when the tab is obscured, while the container is + * animating. + */ + @Test + public void testTabObscured_whileAnimating() { + triggerShow(); + + mMediator.updateTabObscured(true); + // When tab is obscured, Android view should be View.INVISIBLE and composited view should + // be invisible. + + // State 1. All top controls are offset-ed above the screen. + updateBrowserControlParamsAndAssertModel(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT, 0, true, + -(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT), -JAVA_HEIGHT, false, View.INVISIBLE); + + // State 2. Top controls are half-visible. + updateBrowserControlParamsAndAssertModel(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT, 0, true, + -(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT) / 2, + (DEFAULT_CONTAINER_HEIGHT - JAVA_HEIGHT) / 2, false, View.INVISIBLE); + + // State 3. Top controls are fully visible. + updateBrowserControlParamsAndAssertModel(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT, 0, true, 0, + DEFAULT_CONTAINER_HEIGHT, false, View.INVISIBLE); + + // =========================================== + mMediator.updateTabObscured(false); + // Tab is no longer is obscured. Android view should be View.GONE and composited view should + // be visible during animation. + + // State 1. All top controls are offset-ed above the screen. + updateBrowserControlParamsAndAssertModel(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT, 0, true, + -(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT), -JAVA_HEIGHT, false, View.GONE); + + // State 2. Top controls are half-visible. + updateBrowserControlParamsAndAssertModel(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT, 0, true, + -(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT) / 2, + (DEFAULT_CONTAINER_HEIGHT - JAVA_HEIGHT) / 2, true, View.GONE); + + // State 3. Top controls are fully visible. + updateBrowserControlParamsAndAssertModel(DEFAULT_CONTAINER_HEIGHT + JAVA_HEIGHT, 0, true, 0, + DEFAULT_CONTAINER_HEIGHT, false, View.VISIBLE); + } + private void triggerShow() { CallbackHelper heightObserverCallback = new CallbackHelper(); mMediator.addHeightObserver(result -> {
diff --git a/chrome/browser/devtools/protocol/security_handler.cc b/chrome/browser/devtools/protocol/security_handler.cc index cb1adef..f78280c 100644 --- a/chrome/browser/devtools/protocol/security_handler.cc +++ b/chrome/browser/devtools/protocol/security_handler.cc
@@ -172,6 +172,7 @@ NOTREACHED(); return nullptr; + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kNone: case security_state::SafetyTipStatus::kUnknown: return nullptr;
diff --git a/chrome/browser/enterprise/connectors/connectors_prefs.cc b/chrome/browser/enterprise/connectors/connectors_prefs.cc index 0d9a930..c7315619 100644 --- a/chrome/browser/enterprise/connectors/connectors_prefs.cc +++ b/chrome/browser/enterprise/connectors/connectors_prefs.cc
@@ -42,6 +42,10 @@ const char kOnSecurityEventScopePref[] = "enterprise_connectors.scope.on_security_event"; +// Template to store the Box folder_id for caching purposes +constexpr char kFileSystemUploadFolderIdPref[] = + "enterprise_connectors.file_system.box.folder_id"; + namespace { void RegisterFileSystemPrefs(PrefRegistrySimple* registry) {
diff --git a/chrome/browser/enterprise/connectors/connectors_prefs.h b/chrome/browser/enterprise/connectors/connectors_prefs.h index 2a6cff99..12d027e 100644 --- a/chrome/browser/enterprise/connectors/connectors_prefs.h +++ b/chrome/browser/enterprise/connectors/connectors_prefs.h
@@ -43,6 +43,9 @@ // stored there; owtherwise, it will be stored in the local state. extern const char kDeviceTrustPublicKeyPref[]; +// Template to store the service provider's "folder_id" for caching purposes. +extern const char kFileSystemUploadFolderIdPref[]; + void RegisterProfilePrefs(PrefRegistrySimple* registry); void RegisterLocalPrefs(PrefRegistrySimple* registry);
diff --git a/chrome/browser/enterprise/connectors/file_system/access_token_fetcher.cc b/chrome/browser/enterprise/connectors/file_system/access_token_fetcher.cc index 4c98e36..acf2220c1f 100644 --- a/chrome/browser/enterprise/connectors/file_system/access_token_fetcher.cc +++ b/chrome/browser/enterprise/connectors/file_system/access_token_fetcher.cc
@@ -21,6 +21,7 @@ "enterprise_connectors.file_system.%s.access_token"; constexpr char kRefreshTokenPrefPathTemplate[] = "enterprise_connectors.file_system.%s.refresh_token"; +constexpr char kBoxProviderName[] = "box"; // Traffic annotation strings must be fully defined at compile time. They // can't be dynamically built at runtime based on the |service_provider|. @@ -28,7 +29,7 @@ // appropriate annotation for each. net::NetworkTrafficAnnotationTag GetAnnotation( const std::string& service_provider) { - if (service_provider == "box") { + if (service_provider == kBoxProviderName) { return net::DefineNetworkTrafficAnnotation("box_access_token_fetcher", R"( semantics { @@ -125,8 +126,11 @@ base::StringPrintf(kRefreshTokenPrefPathTemplate, service_provider.c_str()), std::string()); - - // TODO(1157641) store folder_id in profile pref to handle indexing latency. + // Currently need this caching only for Box, depending on what other 3P APIs + // look like we may want to do this more generally. + if (service_provider == kBoxProviderName) { + registry->RegisterStringPref(kFileSystemUploadFolderIdPref, std::string()); + } } bool SetFileSystemToken(PrefService* prefs,
diff --git a/chrome/browser/enterprise/connectors/file_system/download_controller.cc b/chrome/browser/enterprise/connectors/file_system/download_controller.cc index 07f389b..a555ec9 100644 --- a/chrome/browser/enterprise/connectors/file_system/download_controller.cc +++ b/chrome/browser/enterprise/connectors/file_system/download_controller.cc
@@ -3,13 +3,14 @@ // found in the LICENSE file. #include "chrome/browser/enterprise/connectors/file_system/download_controller.h" +#include "chrome/browser/enterprise/connectors/connectors_prefs.h" #include "chrome/browser/enterprise/connectors/file_system/box_api_call_flow.h" #include "base/files/file_util.h" +#include "components/prefs/pref_service.h" #include "net/http/http_status_code.h" namespace enterprise_connectors { - FileSystemDownloadController::FileSystemDownloadController( download::DownloadItem* download_item) : local_file_path_(download_item->GetFullPath()), @@ -20,9 +21,18 @@ void FileSystemDownloadController::Init( base::RepeatingCallback<void(void)> authentication_retry_callback, - base::OnceCallback<void(bool)> download_callback) { + base::OnceCallback<void(bool)> download_callback, + PrefService* prefs) { authentication_retry_callback_ = authentication_retry_callback; download_callback_ = std::move(download_callback); + DCHECK(prefs); + prefs_ = prefs; + folder_id_ = prefs_->GetString(kFileSystemUploadFolderIdPref); + if (!folder_id_.empty()) { + // TODO(1190396): Add preflight checks here. + current_api_call_ = CreateUploadApiCall(); + return; + } current_api_call_ = std::make_unique<BoxFindUpstreamFolderApiCallFlow>(base::BindOnce( &FileSystemDownloadController::OnFindUpstreamFolderResponse, @@ -98,6 +108,7 @@ weak_factory_.GetWeakPtr())); } else { folder_id_ = folder_id; + prefs_->SetString(kFileSystemUploadFolderIdPref, folder_id); // Advance to start an upload session. current_api_call_ = CreateUploadApiCall(); } @@ -118,7 +129,7 @@ CHECK_EQ(folder_id.empty(), false); folder_id_ = folder_id; - + prefs_->SetString(kFileSystemUploadFolderIdPref, folder_id); // Advance to start an upload session. current_api_call_ = CreateUploadApiCall(); TryCurrentApiCall();
diff --git a/chrome/browser/enterprise/connectors/file_system/download_controller.h b/chrome/browser/enterprise/connectors/file_system/download_controller.h index 655de5f..fbb707fa 100644 --- a/chrome/browser/enterprise/connectors/file_system/download_controller.h +++ b/chrome/browser/enterprise/connectors/file_system/download_controller.h
@@ -8,6 +8,7 @@ #include "base/files/file_path.h" #include "base/values.h" #include "components/download/public/common/download_item_impl.h" +#include "components/prefs/pref_service.h" #include "google_apis/gaia/oauth2_api_call_flow.h" namespace enterprise_connectors { @@ -29,7 +30,8 @@ // current_api_call_ to be the first step of the whole API call workflow. Must // be called before calling TryTask() for the first time. void Init(base::RepeatingCallback<void(void)> authen_retry_callback, - base::OnceCallback<void(bool)> download_callback); + base::OnceCallback<void(bool)> download_callback, + PrefService* prefs); // Kick off the workflow from the step stored in current_api_call_. Will // re-attempt the last step from where it left off if it called callback with @@ -74,6 +76,7 @@ const base::FilePath local_file_path_; const base::FilePath target_file_name_; const size_t file_size_; + PrefService* prefs_; base::WeakPtrFactory<FileSystemDownloadController> weak_factory_{this}; };
diff --git a/chrome/browser/enterprise/connectors/file_system/download_controller_unittest.cc b/chrome/browser/enterprise/connectors/file_system/download_controller_unittest.cc index 67ff38e..b852495 100644 --- a/chrome/browser/enterprise/connectors/file_system/download_controller_unittest.cc +++ b/chrome/browser/enterprise/connectors/file_system/download_controller_unittest.cc
@@ -12,6 +12,9 @@ #include "base/run_loop.h" #include "base/test/task_environment.h" #include "chrome/browser/enterprise/connectors/file_system/box_api_call_test_helper.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "content/public/test/browser_task_environment.h" #include "content/public/test/fake_download_item.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" @@ -53,17 +56,23 @@ : test_item_(FILE_PATH_LITERAL( "file_system_download_controller_test.txt.crdownload")), controller_(&test_item_), + profile_manager_(TestingBrowserProcess::GetGlobal()), url_factory_( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)) { + EXPECT_TRUE(profile_manager_.SetUp()); + PrefService* prefs = + profile_manager_.CreateTestingProfile("test-user")->GetPrefs(); controller_.Init( base::BindRepeating(&FileSystemDownloadControllerTest::AuthenRetry, weak_factory_.GetWeakPtr()), base::BindOnce(&FileSystemDownloadControllerTest::DownloadComplete, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr()), + prefs); } void SetUp() override { + testing::Test::SetUp(); if (test_item_.GetTemporaryFilePath().empty() || !base::WriteFile(test_item_.GetTemporaryFilePath(), "FileSystemDownloadControllerTest")) { @@ -91,16 +100,17 @@ protected: DownloadItemForTest test_item_; - FileSystemDownloadController controller_; int authentication_retry_{0}; bool download_callback_called_{false}; bool upload_success_{false}; - base::test::TaskEnvironment task_environment_; + content::BrowserTaskEnvironment task_environment_; + // Decoder and TestingProfileManager can only be declared after + // TaskEnvironment. data_decoder::test::InProcessDataDecoder decoder_; - // Decoder can only be declared after TaskEnvironment. + TestingProfileManager profile_manager_; base::OnceClosure quit_closure_;
diff --git a/chrome/browser/enterprise/connectors/file_system/rename_handler.cc b/chrome/browser/enterprise/connectors/file_system/rename_handler.cc index 6371bd2..7a4f739 100644 --- a/chrome/browser/enterprise/connectors/file_system/rename_handler.cc +++ b/chrome/browser/enterprise/connectors/file_system/rename_handler.cc
@@ -107,7 +107,8 @@ base::BindRepeating(&FileSystemRenameHandler::OnApiAuthenticationError, weak_factory_.GetWeakPtr()), base::BindOnce(&FileSystemRenameHandler::NotifyResultToDownloadThread, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr()), + GetPrefs()); StartInternal(); }
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc index c8a49f16..dd765e96 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
@@ -669,6 +669,36 @@ profile->GetPrefs(), language_model)))); } +LanguageSettingsPrivateSetTranslateTargetLanguageFunction:: + LanguageSettingsPrivateSetTranslateTargetLanguageFunction() + : chrome_details_(this) {} + +LanguageSettingsPrivateSetTranslateTargetLanguageFunction:: + ~LanguageSettingsPrivateSetTranslateTargetLanguageFunction() = default; + +ExtensionFunction::ResponseAction +LanguageSettingsPrivateSetTranslateTargetLanguageFunction::Run() { + const auto parameters = + language_settings_private::SetTranslateTargetLanguage::Params::Create( + *args_); + EXTENSION_FUNCTION_VALIDATE(parameters.get()); + const std::string& language_code = parameters->language_code; + + std::unique_ptr<translate::TranslatePrefs> translate_prefs = + ChromeTranslateClient::CreateTranslatePrefs( + chrome_details_.GetProfile()->GetPrefs()); + + std::string chrome_language = language_code; + translate_prefs->AddToLanguageList(language_code, false); + + if (language_code == translate_prefs->GetRecentTargetLanguage()) { + return RespondNow(NoArguments()); + } + translate_prefs->SetRecentTargetLanguage(language_code); + + return RespondNow(NoArguments()); +} + #if BUILDFLAG(IS_CHROMEOS_ASH) // Populates the vector of input methods using information in the list of // descriptors. Used for languageSettingsPrivate.getInputMethodLists().
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.h b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.h index 8d0d63e..51ff4c6 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.h +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.h
@@ -270,6 +270,28 @@ LanguageSettingsPrivateGetTranslateTargetLanguageFunction); }; +// Implements the languageSettingsPrivate.setTranslateTargetLanguage method. +class LanguageSettingsPrivateSetTranslateTargetLanguageFunction + : public ExtensionFunction { + public: + LanguageSettingsPrivateSetTranslateTargetLanguageFunction(); + DECLARE_EXTENSION_FUNCTION( + "languageSettingsPrivate.setTranslateTargetLanguage", + LANGUAGESETTINGSPRIVATE_SETTRANSLATETARGETLANGUAGE) + + protected: + ~LanguageSettingsPrivateSetTranslateTargetLanguageFunction() override; + + // ExtensionFunction overrides. + ResponseAction Run() override; + + private: + ChromeExtensionFunctionDetails chrome_details_; + + DISALLOW_COPY_AND_ASSIGN( + LanguageSettingsPrivateSetTranslateTargetLanguageFunction); +}; + // Implements the languageSettingsPrivate.getInputMethodLists method. class LanguageSettingsPrivateGetInputMethodListsFunction : public ExtensionFunction {
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc index 576fc8a..f4831986 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
@@ -238,6 +238,36 @@ } } +TEST_F(LanguageSettingsPrivateApiTest, SetTranslateTargetLanguageTest) { + std::unique_ptr<translate::TranslatePrefs> translate_prefs_ = + ChromeTranslateClient::CreateTranslatePrefs(profile()->GetPrefs()); + + std::vector<std::string> content_languages_before; + translate_prefs_->GetLanguageList(&content_languages_before); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + ASSERT_EQ(std::vector<std::string>({"en-US"}), content_languages_before); +#else + ASSERT_EQ(std::vector<std::string>({"en-US", "en"}), + content_languages_before); +#endif + translate_prefs_->SetRecentTargetLanguage("en"); + ASSERT_EQ(translate_prefs_->GetRecentTargetLanguage(), "en"); + + auto function = base::MakeRefCounted< + LanguageSettingsPrivateSetTranslateTargetLanguageFunction>(); + + std::unique_ptr<base::Value> result = + api_test_utils::RunFunctionAndReturnSingleResult(function.get(), + "[\"af\"]", profile()); + ASSERT_EQ(translate_prefs_->GetRecentTargetLanguage(), "af"); + + std::vector<std::string> content_languages_after; + translate_prefs_->GetLanguageList(&content_languages_after); + ASSERT_EQ(std::vector<std::string>({"en-US", "en", "af"}), + content_languages_after); +} + TEST_F(LanguageSettingsPrivateApiTest, GetLanguageListTest) { translate::TranslateDownloadManager::GetInstance()->ResetForTesting(); RunGetLanguageListTest();
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 1a12940..f5fce22 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -318,6 +318,8 @@ settings_api::PrefType::PREF_TYPE_STRING; (*s_allowlist)[language::prefs::kForcedLanguages] = settings_api::PrefType::PREF_TYPE_LIST; + (*s_allowlist)[translate::TranslatePrefs::kPrefTranslateRecentTarget] = + settings_api::PrefType::PREF_TYPE_STRING; #if BUILDFLAG(IS_CHROMEOS_ASH) (*s_allowlist)[::prefs::kLanguageImeMenuActivated] = settings_api::PrefType::PREF_TYPE_BOOLEAN;
diff --git a/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc b/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc index 705184ea..686eedd 100644 --- a/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc +++ b/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc
@@ -26,7 +26,8 @@ sync_pb::SyncEnums_DeviceType_TYPE_LINUX, device_id, "manufacturer", "model", base::Time(), syncer::DeviceInfoUtil::GetPulseInterval(), /*send_tab_to_self_receiving_enabled=*/true, - /*sharing_info=*/base::nullopt, /*fcm_registration_token=*/std::string(), + /*sharing_info=*/base::nullopt, /*paask_info=*/base::nullopt, + /*fcm_registration_token=*/std::string(), /*interested_data_types=*/syncer::ModelTypeSet()); } } // namespace
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc index 618dd9c..3a14247 100644 --- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc +++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc
@@ -37,6 +37,7 @@ "model", base::Time(), syncer::DeviceInfoUtil::GetPulseInterval(), /*send_tab_to_self_receiving_enabled=*/true, /*sharing_info=*/base::nullopt, + /*passk_info=*/base::nullopt, /*fcm_registration_token=*/std::string(), /*interested_data_types=*/syncer::ModelTypeSet()); }
diff --git a/chrome/browser/extensions/manifest_v3_browsertest.cc b/chrome/browser/extensions/manifest_v3_browsertest.cc index ac2c677..fb9631e 100644 --- a/chrome/browser/extensions/manifest_v3_browsertest.cc +++ b/chrome/browser/extensions/manifest_v3_browsertest.cc
@@ -53,7 +53,7 @@ })"; constexpr char kWorker[] = R"(chrome.tabs.onUpdated.addListener( - function listener(tabId, changeInfo, tab) { + async function listener(tabId, changeInfo, tab) { if (changeInfo.status != 'complete') return; let url = new URL(tab.url); @@ -62,6 +62,7 @@ // The tabs API equivalents of script injection are removed in MV3. chrome.test.assertEq(undefined, chrome.tabs.executeScript); chrome.test.assertEq(undefined, chrome.tabs.insertCSS); + chrome.test.assertEq(undefined, chrome.tabs.removeCSS); chrome.tabs.onUpdated.removeListener(listener); @@ -69,18 +70,18 @@ document.title = 'My New Title'; return document.title; } - chrome.scripting.executeScript( - { - target: {tabId: tabId}, - function: injectedFunction, - }, - (results) => { - chrome.test.assertNoLastError(); - chrome.test.assertTrue(!!results); - chrome.test.assertEq(1, results.length); - chrome.test.assertEq('My New Title', results[0].result); - chrome.test.notifyPass(); - }); + try { + const results = await chrome.scripting.executeScript({ + target: {tabId: tabId}, + function: injectedFunction, + }); + chrome.test.assertTrue(!!results); + chrome.test.assertEq(1, results.length); + chrome.test.assertEq('My New Title', results[0].result); + chrome.test.notifyPass(); + } catch(error) { + chrome.test.notifyFail('executeScript promise rejected'); + } }); chrome.test.sendMessage('ready');)";
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index fd0ea95..8d64b30 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -363,6 +363,11 @@ "expiry_milestone": 95 }, { + "name": "autofill-parse-merchant-promo-code-fields", + "owners": [ "jsaul@google.com", "payments-autofill-team@google.com" ], + "expiry_milestone": 97 + }, + { "name": "autofill-profile-client-validation", "owners": [ "parastoog" ], "expiry_milestone": 79 @@ -1466,6 +1471,12 @@ "expiry_milestone": 90 }, { + "name": "enable-container-queries", + "owners": [ "andruud", "futhark" ], + // This flag is used to get developer feedback on the API. + "expiry_milestone": 97 + }, + { "name": "enable-cooperative-scheduling", "owners": [ "keishi" ], "expiry_milestone": 85
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b85b7fe..30b8fb8 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -78,6 +78,11 @@ const char kCOLRV1FontsDescription[] = "Display COLR v1 color gradient vector fonts."; +extern const char kCSSContainerQueriesName[] = "Enable CSS Container Queries"; +extern const char kCSSContainerQueriesDescription[] = + "Enables support for @container, inline-size and block-size values for the " + "contain property, and the LayoutNG Grid implementation."; + const char kConditionalTabStripAndroidName[] = "Conditional Tab Strip"; const char kConditionalTabStripAndroidDescription[] = "Allows users to access conditional tab strip."; @@ -280,6 +285,12 @@ "When enabled, if all requirements are met, Autofill will offer to use " "virtual credit cards in form filling."; +const char kAutofillParseMerchantPromoCodeFieldsName[] = + "Parse promo code fields in forms"; +const char kAutofillParseMerchantPromoCodeFieldsDescription[] = + "When enabled, Autofill will attempt to find merchant promo/coupon/gift " + "code fields when parsing forms."; + const char kAutofillProfileClientValidationName[] = "Autofill Validates Profiles By Client"; const char kAutofillProfileClientValidationDescription[] = @@ -4086,10 +4097,6 @@ const char kEnableAssistantRoutinesName[] = "Assistant Routines"; const char kEnableAssistantRoutinesDescription[] = "Enable Assistant Routines."; -const char kEnableAssistantTimersV2Name[] = "Enable Assistant Timers V2"; -const char kEnableAssistantTimersV2Description[] = - "Enables v2 of Assistant timers."; - const char kEnableAutoSelectName[] = "Auto Select"; const char kEnableAutoSelectDescription[] = "Automatically select the word under cursor on contextual menu click.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 3662a711..8490126a 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -83,6 +83,9 @@ extern const char kCOLRV1FontsName[]; extern const char kCOLRV1FontsDescription[]; +extern const char kCSSContainerQueriesName[]; +extern const char kCSSContainerQueriesDescription[]; + extern const char kContentLanguagesInLanguagePickerName[]; extern const char kContentLanguagesInLanguagePickerDescription[]; @@ -174,6 +177,9 @@ extern const char kAutofillEnableVirtualCardName[]; extern const char kAutofillEnableVirtualCardDescription[]; +extern const char kAutofillParseMerchantPromoCodeFieldsName[]; +extern const char kAutofillParseMerchantPromoCodeFieldsDescription[]; + extern const char kAutofillProfileClientValidationName[]; extern const char kAutofillProfileClientValidationDescription[]; @@ -2324,9 +2330,6 @@ extern const char kDriveFsBidirectionalNativeMessagingName[]; extern const char kDriveFsBidirectionalNativeMessagingDescription[]; -extern const char kEnableAdvancedPpdAttributesName[]; -extern const char kEnableAdvancedPpdAttributesDescription[]; - extern const char kEnableAppDataSearchName[]; extern const char kEnableAppDataSearchDescription[]; @@ -2360,9 +2363,6 @@ extern const char kEnableAssistantRoutinesName[]; extern const char kEnableAssistantRoutinesDescription[]; -extern const char kEnableAssistantTimersV2Name[]; -extern const char kEnableAssistantTimersV2Description[]; - extern const char kEnableAutoSelectName[]; extern const char kEnableAutoSelectDescription[];
diff --git a/chrome/browser/flags/BUILD.gn b/chrome/browser/flags/BUILD.gn index 135f751..52e982170 100644 --- a/chrome/browser/flags/BUILD.gn +++ b/chrome/browser/flags/BUILD.gn
@@ -6,6 +6,7 @@ android_library("java") { sources = [ + "android/java/src/org/chromium/chrome/browser/flags/AllCachedFieldTrialParameters.java", "android/java/src/org/chromium/chrome/browser/flags/BooleanCachedFieldTrialParameter.java", "android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java", "android/java/src/org/chromium/chrome/browser/flags/CachedFieldTrialParameter.java",
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/AllCachedFieldTrialParameters.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/AllCachedFieldTrialParameters.java new file mode 100644 index 0000000..3d502e4 --- /dev/null +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/AllCachedFieldTrialParameters.java
@@ -0,0 +1,74 @@ +// 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.flags; + +import androidx.annotation.VisibleForTesting; + +import org.json.JSONException; +import org.json.JSONObject; + +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * AllCachedFieldTrialParameters caches all the parameters for a feature. + */ +public class AllCachedFieldTrialParameters extends CachedFieldTrialParameter { + /** + * Decodes a previously encoded map. Returns empty map on parse error. + */ + private static Map<String, String> decodeJsonEncodedMap(String value) { + Map<String, String> resultingMap = new HashMap<String, String>(); + try { + final JSONObject json = new JSONObject(value); + Iterator<String> keys = json.keys(); + while (keys.hasNext()) { + final String key = keys.next(); + resultingMap.put(key, json.getString(key)); + } + return resultingMap; + } catch (JSONException e) { + } + return new HashMap<>(); + } + + private static String encodeParams(Map<String, String> params) { + return new JSONObject(params).toString(); + } + + public AllCachedFieldTrialParameters(String featureName) { + // As this includes all parameters, the parameterName is empty. + super(featureName, /* parameterName */ "", FieldTrialParameterType.ALL, + /* preferenceKeyOverride */ null); + } + + /** + * Returns a map of field trial parameter to value. + */ + public Map<String, String> getParams() { + return decodeJsonEncodedMap( + CachedFeatureFlags.getConsistentStringValue(getSharedPreferenceKey(), "")); + } + + @Override + void cacheToDisk() { + final Map<String, String> params = + ChromeFeatureList.getFieldTrialParamsForFeature(getFeatureName()); + SharedPreferencesManager.getInstance().writeString( + getSharedPreferenceKey(), encodeParams(params)); + } + + /** + * Sets the parameters for the specified feature when used in tests. + */ + @VisibleForTesting + public static void setForTesting(String featureName, Map<String, String> params) { + CachedFeatureFlags.setOverrideTestValue( + generateSharedPreferenceKey(featureName, ""), encodeParams(params)); + } +}
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java index 3303b19d..e3efc4c7 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -83,6 +83,7 @@ put(ChromeFeatureList.CCT_REMOVE_REMOTE_VIEW_IDS, true); put(ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK, false); put(ChromeFeatureList.CCT_INCOGNITO, true); + put(ChromeFeatureList.EXPERIMENTS_FOR_AGSA, true); } }; @@ -268,6 +269,20 @@ } } + public static void cacheMinimalBrowserFlagsTimeFromNativeTime() { + SharedPreferencesManager.getInstance().writeLong( + ChromePreferenceKeys.FLAGS_LAST_CACHED_MINIMAL_BROWSER_FLAGS_TIME_MILLIS, + System.currentTimeMillis()); + } + + /** + * Returns the time (in millis) the minimal browser flags were cached. + */ + public static long getLastCachedMinimalBrowserFlagsTimeMillis() { + return SharedPreferencesManager.getInstance().readLong( + ChromePreferenceKeys.FLAGS_LAST_CACHED_MINIMAL_BROWSER_FLAGS_TIME_MILLIS, 0); + } + /** * Cache whether warming up network service process is enabled, so that the value * can be made available immediately on next start up.
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsUnitTest.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsUnitTest.java index 5b92a11c..2205cb5b 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsUnitTest.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsUnitTest.java
@@ -6,6 +6,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.After; import org.junit.Before; @@ -183,4 +184,13 @@ CachedFeatureFlags.swapDefaultsForTesting(previousDefaults); } } + + @Test + public void testGetLastCachedMinimalBrowserFlagsTimeMillis() { + // Initial time is 0. + assertEquals(0, CachedFeatureFlags.getLastCachedMinimalBrowserFlagsTimeMillis()); + final long timeMillis = System.currentTimeMillis(); + CachedFeatureFlags.cacheMinimalBrowserFlagsTimeFromNativeTime(); + assertTrue(CachedFeatureFlags.getLastCachedMinimalBrowserFlagsTimeMillis() >= timeMillis); + } }
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFieldTrialParameter.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFieldTrialParameter.java index 2e21beb..f742bfc2 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFieldTrialParameter.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFieldTrialParameter.java
@@ -24,13 +24,15 @@ * Data types of field trial parameters. */ @IntDef({FieldTrialParameterType.STRING, FieldTrialParameterType.BOOLEAN, - FieldTrialParameterType.INT, FieldTrialParameterType.DOUBLE}) + FieldTrialParameterType.INT, FieldTrialParameterType.DOUBLE, + FieldTrialParameterType.ALL}) @Retention(RetentionPolicy.SOURCE) public @interface FieldTrialParameterType { int STRING = 0; int BOOLEAN = 1; int INT = 2; int DOUBLE = 3; + int ALL = 4; } @CheckDiscard("crbug.com/1067145") @@ -44,6 +46,8 @@ CachedFieldTrialParameter(String featureName, String parameterName, @FieldTrialParameterType int type, String preferenceKeyOverride) { mFeatureName = featureName; + // parameterName does not apply to ALL (because it includes all parameters). + assert type != FieldTrialParameterType.ALL || parameterName.isEmpty(); mParameterName = parameterName; mType = type; mPreferenceKeyOverride = preferenceKeyOverride;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FieldTrialsInstrumentationTest.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FieldTrialsInstrumentationTest.java index 64cbc1f..8c4d139 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FieldTrialsInstrumentationTest.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/FieldTrialsInstrumentationTest.java
@@ -19,6 +19,9 @@ import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.FieldTrials; +import java.util.HashMap; +import java.util.Map; + /** * Tests for {@link FieldTrials}. */ @@ -146,4 +149,24 @@ Features.ensureCommandLineIsUpToDate(); Assert.assertEquals("b1", parameter.getValue()); } + + @Test + @SmallTest + // clang-format off + @CommandLineFlags.Add({"enable-features=" + sFeature2 + "<Study", + "force-fieldtrials=Study/Group", + "force-fieldtrial-params=Study.Group:101/x/y/99"}) + public void testAllCachedFieldTrialParameters() { + AllCachedFieldTrialParameters parameters = new AllCachedFieldTrialParameters(sFeature2); + Map<String, String> expectedFeatures = new HashMap<>(); + expectedFeatures.put("101", "x"); + expectedFeatures.put("y", "99"); + Assert.assertEquals(expectedFeatures, parameters.getParams()); + } + + @Test + @SmallTest + public void testGetLastUpdateFromNativeTimeMillis() { + Assert.assertNotEquals(0, CachedFeatureFlags.getLastCachedMinimalBrowserFlagsTimeMillis()); + } }
diff --git a/chrome/browser/infobars/infobars_browsertest.cc b/chrome/browser/infobars/infobars_browsertest.cc index 3447bee..d2ad389 100644 --- a/chrome/browser/infobars/infobars_browsertest.cc +++ b/chrome/browser/infobars/infobars_browsertest.cc
@@ -63,7 +63,6 @@ #if defined(OS_MAC) #include "chrome/browser/ui/cocoa/keystone_infobar_delegate.h" -#include "chrome/browser/ui/cocoa/rosetta_required_infobar_delegate.h" #endif #if !defined(USE_AURA) @@ -200,7 +199,6 @@ {"translate", IBD::TRANSLATE_INFOBAR_DELEGATE_NON_AURA}, {"automation", IBD::AUTOMATION_INFOBAR_DELEGATE}, {"tab_sharing", IBD::TAB_SHARING_INFOBAR_DELEGATE}, - {"rosetta_required", IBD::ROSETTA_REQUIRED_INFOBAR_DELEGATE}, }; auto id_entry = kIdentifiers.find(name); if (id_entry == kIdentifiers.end()) { @@ -361,14 +359,6 @@ nullptr); break; - case IBD::ROSETTA_REQUIRED_INFOBAR_DELEGATE: -#if defined(OS_MAC) - RosettaRequiredInfoBarDelegate::Create(GetWebContents()); -#else - ADD_FAILURE() << "This infobar is not supported on this OS."; -#endif - break; - default: break; }
diff --git a/chrome/browser/language/android/BUILD.gn b/chrome/browser/language/android/BUILD.gn index 32769132..d5770d09 100644 --- a/chrome/browser/language/android/BUILD.gn +++ b/chrome/browser/language/android/BUILD.gn
@@ -21,12 +21,14 @@ android_library("java") { sources = [ "java/src/org/chromium/chrome/browser/language/settings/AddLanguageFragment.java", - "java/src/org/chromium/chrome/browser/language/settings/AlwaysTranslateLanguagesFragment.java", + "java/src/org/chromium/chrome/browser/language/settings/AlwaysTranslateListFragment.java", "java/src/org/chromium/chrome/browser/language/settings/AvailableUiLanguages.java", + "java/src/org/chromium/chrome/browser/language/settings/ContentLanguagesPreference.java", "java/src/org/chromium/chrome/browser/language/settings/LanguageItem.java", + "java/src/org/chromium/chrome/browser/language/settings/LanguageItemListFragment.java", + "java/src/org/chromium/chrome/browser/language/settings/LanguageItemListPreference.java", "java/src/org/chromium/chrome/browser/language/settings/LanguageItemPickerPreference.java", "java/src/org/chromium/chrome/browser/language/settings/LanguageListBaseAdapter.java", - "java/src/org/chromium/chrome/browser/language/settings/LanguageListPreference.java", "java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java", "java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java",
diff --git a/chrome/browser/language/android/java/res/xml/languages_detailed_preferences.xml b/chrome/browser/language/android/java/res/xml/languages_detailed_preferences.xml index 02154c9..0c08075 100644 --- a/chrome/browser/language/android/java/res/xml/languages_detailed_preferences.xml +++ b/chrome/browser/language/android/java/res/xml/languages_detailed_preferences.xml
@@ -22,7 +22,7 @@ android:order="2" app:allowDividerAbove="true"> - <org.chromium.chrome.browser.language.settings.LanguageListPreference + <org.chromium.chrome.browser.language.settings.ContentLanguagesPreference android:key="content_languages_preference" android:layout="@layout/languages_preference" android:widgetLayout="@layout/accept_languages_list" /> @@ -56,10 +56,9 @@ app:allowDividerAbove="false" app:allowDividerBelow="false" /> - <org.chromium.components.browser_ui.settings.ChromeBasePreference + <org.chromium.chrome.browser.language.settings.LanguageItemListPreference android:key="translate_settings_always_languages" android:title="@string/languages_settings_automatic" - android:fragment="org.chromium.chrome.browser.language.settings.AlwaysTranslateLanguagesFragment" app:allowDividerAbove="false" app:allowDividerBelow="false" />
diff --git a/chrome/browser/language/android/java/res/xml/languages_preferences.xml b/chrome/browser/language/android/java/res/xml/languages_preferences.xml index e2499725..91fa447 100644 --- a/chrome/browser/language/android/java/res/xml/languages_preferences.xml +++ b/chrome/browser/language/android/java/res/xml/languages_preferences.xml
@@ -6,7 +6,7 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - <org.chromium.chrome.browser.language.settings.LanguageListPreference + <org.chromium.chrome.browser.language.settings.ContentLanguagesPreference android:key="preferred_languages" android:layout="@layout/languages_preference" android:widgetLayout="@layout/accept_languages_list" />
diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/AlwaysTranslateListFragment.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/AlwaysTranslateListFragment.java new file mode 100644 index 0000000..5afee5c --- /dev/null +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/AlwaysTranslateListFragment.java
@@ -0,0 +1,54 @@ +// 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.language.settings; + +import android.content.Context; + +import org.chromium.chrome.browser.language.R; +import org.chromium.chrome.browser.translate.TranslateBridge; + +import java.util.Collection; + +/** + * Chrome Fragment for the always translate that provides UI for adding and removing languages. + * Should be launched from a {@link LanguageItemListPreference}. + */ +public class AlwaysTranslateListFragment extends LanguageItemListFragment { + @Override + protected LanguageItemListFragment.ListDelegate makeFragmentListDelegate() { + return new ListDelegate(); + } + + @Override + protected String getLanguageListTitle(Context context) { + return context.getResources().getString(R.string.languages_settings_automatic_title); + } + + @Override + protected void onLanguageAdded(String code) { + TranslateBridge.setLanguageAlwaysTranslateState(code, true); + } + + @Override + protected void onLanguageRemoved(String code) { + TranslateBridge.setLanguageAlwaysTranslateState(code, false); + } + + /** + * Helper class to populate the LanguageItem list and used by {@link LanguageItemListPreference} + * to make the summary text and launch an Intent to this Fragment. + */ + public static class ListDelegate implements LanguageItemListFragment.ListDelegate { + @Override + public Collection<LanguageItem> getLanguageItems() { + return LanguagesManager.getInstance().getAlwaysTranslateLanguageItems(); + } + + @Override + public String getFragmentClassName() { + return AlwaysTranslateListFragment.class.getName(); + } + } +}
diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListPreference.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/ContentLanguagesPreference.java similarity index 98% rename from chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListPreference.java rename to chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/ContentLanguagesPreference.java index 349dcc1..a10bf4e 100644 --- a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageListPreference.java +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/ContentLanguagesPreference.java
@@ -33,7 +33,7 @@ /** * A preference that displays the current accept language list. */ -public class LanguageListPreference extends Preference { +public class ContentLanguagesPreference extends Preference { private static class LanguageListAdapter extends LanguageListBaseAdapter implements LanguagesManager.AcceptLanguageObserver { private final Context mContext; @@ -138,7 +138,7 @@ private LanguageListAdapter mAdapter; private AddLanguageFragment.Launcher mLauncher; - public LanguageListPreference(Context context, AttributeSet attrs) { + public ContentLanguagesPreference(Context context, AttributeSet attrs) { super(context, attrs); mAdapter = new LanguageListAdapter(context); }
diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/AlwaysTranslateLanguagesFragment.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageItemListFragment.java similarity index 65% rename from chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/AlwaysTranslateLanguagesFragment.java rename to chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageItemListFragment.java index 39a2cb8..b43edb7 100644 --- a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/AlwaysTranslateLanguagesFragment.java +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageItemListFragment.java
@@ -13,6 +13,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ScrollView; import android.widget.TextView; import androidx.fragment.app.Fragment; @@ -22,7 +23,6 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder; import org.chromium.chrome.browser.language.R; -import org.chromium.chrome.browser.translate.TranslateBridge; import org.chromium.components.browser_ui.settings.FragmentSettingsLauncher; import org.chromium.components.browser_ui.settings.SettingsLauncher; import org.chromium.components.browser_ui.settings.SettingsUtils; @@ -32,16 +32,35 @@ import org.chromium.components.browser_ui.widget.listmenu.ListMenuItemProperties; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; +import java.util.Collection; + /** - * Fragment that lists the languages that are always translated. Languages can be removed via the - * overflow menu and added with the `Add Language` button. + * Base Fragment for an editable list of LanguageItems. Languages can be removed via the overflow + * menu and added with the `Add Language` button. Subclasses will override makeFragmentListDelegate + * to populate the LanguageItem list and provide callbacks for adding and removing items. */ -public class AlwaysTranslateLanguagesFragment extends Fragment implements FragmentSettingsLauncher { - // Request code for returning from Select Language +public abstract class LanguageItemListFragment + extends Fragment implements FragmentSettingsLauncher { + // Request code for returning from Select Language Fragment private static final int REQUEST_CODE_SELECT_LANGUAGE = 1; - private class AlwaysTranslateLanguageListAdapter extends LanguageListBaseAdapter { - AlwaysTranslateLanguageListAdapter(Context context) { + /** + * Interface for helper functions to populate the LanguageItem list and used by + * {@link LanguageItemListPreference} to make a summary and launch the correct Fragment. + */ + public interface ListDelegate { + /** + * Return LanguageItems to show in LanguageItemListFragment. + */ + Collection<LanguageItem> getLanguageItems(); + /** + * Return class name to launch this LanguageItemListFragment from an Intent. + */ + String getFragmentClassName(); + } + + private class ListAdapter extends LanguageListBaseAdapter { + ListAdapter(Context context) { super(context); } @@ -58,8 +77,7 @@ ListMenu.Delegate delegate = (model) -> { int textId = model.get(ListMenuItemProperties.TITLE_ID); if (textId == R.string.remove) { - TranslateBridge.setLanguageAlwaysTranslateState( - currentLanguageItem.getCode(), false); + onLanguageRemoved(currentLanguageItem.getCode()); onDataUpdated(); } }; @@ -69,17 +87,19 @@ } public void onDataUpdated() { - setDisplayedLanguages(LanguagesManager.getInstance().getAlwaysTranslateLanguageItems()); + setDisplayedLanguages(mListDelegate.getLanguageItems()); } } private SettingsLauncher mSettingsLauncher; - private AlwaysTranslateLanguageListAdapter mAdapter; + private ListAdapter mAdapter; + private ListDelegate mListDelegate; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getActivity().setTitle(R.string.languages_settings_automatic_title); + mListDelegate = makeFragmentListDelegate(); + getActivity().setTitle(getLanguageListTitle(getContext())); } @Override @@ -96,13 +116,13 @@ mRecyclerView.addItemDecoration( new DividerItemDecoration(activity, layoutManager.getOrientation())); - mAdapter = new AlwaysTranslateLanguageListAdapter(activity); + mAdapter = new ListAdapter(activity); mRecyclerView.setAdapter(mAdapter); mAdapter.onDataUpdated(); - inflatedView.findViewById(R.id.scroll_view) - .getViewTreeObserver() - .addOnScrollChangedListener(SettingsUtils.getShowShadowOnScrollListener( - mRecyclerView, inflatedView.findViewById(R.id.shadow))); + ScrollView scrollView = inflatedView.findViewById(R.id.scroll_view); + scrollView.getViewTreeObserver().addOnScrollChangedListener( + SettingsUtils.getShowShadowOnScrollListener( + scrollView, inflatedView.findViewById(R.id.shadow))); TextView addLanguageButton = (TextView) inflatedView.findViewById(R.id.add_language); addLanguageButton.setCompoundDrawablesRelativeWithIntrinsicBounds( @@ -126,7 +146,7 @@ super.onActivityResult(requestCode, requestCode, data); if (requestCode == REQUEST_CODE_SELECT_LANGUAGE && resultCode == Activity.RESULT_OK) { String code = data.getStringExtra(AddLanguageFragment.INTENT_SELECTED_LANGUAGE); - TranslateBridge.setLanguageAlwaysTranslateState(code, true); + onLanguageAdded(code); mAdapter.onDataUpdated(); } } @@ -135,4 +155,24 @@ public void setSettingsLauncher(SettingsLauncher settingsLauncher) { mSettingsLauncher = settingsLauncher; } + + /** + * Return the ListDelegate that will be used to populate the LangaugeItemList for a subclass. + */ + protected abstract LanguageItemListFragment.ListDelegate makeFragmentListDelegate(); + + /** + * Return title for LanguageItemListFragment. + */ + protected abstract String getLanguageListTitle(Context context); + + /** + * Callback for when a language is added to the LanguageItemList. + */ + protected abstract void onLanguageAdded(String code); + + /** + * Callback for when a language is removed to the LanguageItemList. + */ + protected abstract void onLanguageRemoved(String code); }
diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageItemListPreference.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageItemListPreference.java new file mode 100644 index 0000000..89f3561 --- /dev/null +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageItemListPreference.java
@@ -0,0 +1,80 @@ +// 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.language.settings; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; + +import org.chromium.chrome.browser.preferences.PrefChangeRegistrar; +import org.chromium.components.browser_ui.settings.ChromeBasePreference; + +import java.util.ArrayList; + +/** + * Chrome Preference that is used to launch a {@link LanguageItemListFragment}. The preference + * summary is updated to refelect the first elements of the list. + */ +public class LanguageItemListPreference + extends ChromeBasePreference implements PrefChangeRegistrar.PrefObserver { + // Default number of items to list in a collection preference summary. + private static final int COLLECTION_SUMMARY_ITEM_LIMIT = 3; + + private LanguageItemListFragment.ListDelegate mLanguageItemListDelegate; + + public LanguageItemListPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setFragmentListDelegate(LanguageItemListFragment.ListDelegate listDelegate) { + mLanguageItemListDelegate = listDelegate; + updateSummary(); + } + + /** + * @return The name of the Fragment to launch when this preference is clicked. + */ + public String getFragmentClassName() { + return mLanguageItemListDelegate.getFragmentClassName(); + } + + /** + * If the LanguageItemListDelegate for this preference is set and has languages to show update + * the summary. Otherwise leave the summary as is. + */ + public void updateSummary() { + String summary = makeSummary(); + if (TextUtils.isEmpty(summary)) return; + setSummary(summary); + } + + /** + * Allows this preference to be registared as a preference observer and update the summary when + * the preference changes. From {@link PrefChangeRegistrar.PrefObserver}. + */ + @Override + public void onPreferenceChange() { + updateSummary(); + } + + /** + * If the ListDelegate for this preference is set return a comma separated string of + * display names for at most the first three languages. If the list is empty or delegate is not + * set return the empty string. + * @param languages List of LanguageItems. + * @return Comma sepperated string of language display names. + */ + private String makeSummary() { + if (mLanguageItemListDelegate == null) return ""; + int index = 0; + ArrayList<String> languageNames = new ArrayList<String>(); + for (LanguageItem item : mLanguageItemListDelegate.getLanguageItems()) { + if (++index > COLLECTION_SUMMARY_ITEM_LIMIT) break; + languageNames.add(item.getDisplayName()); + } + // TODO(crbug.com/1181224): Make sure to localize the separator. + return TextUtils.join(", ", languageNames); + } +}
diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java index a6c2248e..02f48de 100644 --- a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/settings/LanguageSettings.java
@@ -21,10 +21,10 @@ import org.chromium.chrome.browser.language.LanguageSplitInstaller; import org.chromium.chrome.browser.language.R; import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.preferences.PrefChangeRegistrar; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate; import org.chromium.chrome.browser.translate.TranslateBridge; -import org.chromium.components.browser_ui.settings.ChromeBasePreference; import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; import org.chromium.components.browser_ui.settings.FragmentSettingsLauncher; import org.chromium.components.browser_ui.settings.SettingsLauncher; @@ -32,18 +32,12 @@ import org.chromium.components.prefs.PrefService; import org.chromium.components.user_prefs.UserPrefs; -import java.util.ArrayList; -import java.util.Collection; - /** * Settings fragment that displays information about Chrome languages, which allow users to * seamlessly find and manage their languages preferences across platforms. */ public class LanguageSettings extends PreferenceFragmentCompat implements AddLanguageFragment.Launcher, FragmentSettingsLauncher { - // Default number of items to list in a collection preference summary. - private static final int COLLECTION_SUMMARY_ITEM_LIMIT = 3; - // Return codes from launching Intents on preferences. private static final int REQUEST_CODE_ADD_ACCEPT_LANGUAGE = 1; private static final int REQUEST_CODE_CHANGE_APP_LANGUAGE = 2; @@ -64,10 +58,12 @@ // SettingsLauncher injected from main Settings Activity. private SettingsLauncher mSettingsLauncher; + private PrefChangeRegistrar mPrefChangeRegistrar; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { getActivity().setTitle(R.string.language_settings); + mPrefChangeRegistrar = new PrefChangeRegistrar(); // Show the detailed language settings if DETAILED_LANGUAGE_SETTINGS feature is enabled. if (ChromeFeatureList.isEnabled(ChromeFeatureList.DETAILED_LANGUAGE_SETTINGS)) { @@ -85,8 +81,8 @@ private void createBasicPreferences(Bundle savedInstanceState, String rootKey) { SettingsUtils.addPreferencesFromResource(this, R.xml.languages_preferences); - LanguageListPreference mLanguageListPref = - (LanguageListPreference) findPreference(PREFERRED_LANGUAGES_KEY); + ContentLanguagesPreference mLanguageListPref = + (ContentLanguagesPreference) findPreference(PREFERRED_LANGUAGES_KEY); mLanguageListPref.registerActivityLauncher(this); ChromeSwitchPreference translateSwitch = @@ -125,8 +121,8 @@ setupAppLanguageSection(); - LanguageListPreference mLanguageListPref = - (LanguageListPreference) findPreference(CONTENT_LANGUAGES_KEY); + ContentLanguagesPreference mLanguageListPref = + (ContentLanguagesPreference) findPreference(CONTENT_LANGUAGES_KEY); mLanguageListPref.registerActivityLauncher(this); setupTranslateSection(mLanguageListPref); @@ -154,14 +150,10 @@ /** * Setup the translate preferences section. A switch preferences controls if translate is * enabled/disabled and will hide all advanced settings when disabled. - * @param languageListPreference LanguageListPreference reference to update about state changes. + * @param contentLanguagesPreference ContentLanguagesPreference reference to update about state + * changes. */ - private void setupTranslateSection(LanguageListPreference languageListPreference) { - ChromeSwitchPreference translateSwitch = - (ChromeSwitchPreference) findPreference(TRANSLATE_SWITCH_KEY); - boolean isTranslateEnabled = getPrefService().getBoolean(Pref.OFFER_TRANSLATE_ENABLED); - translateSwitch.setChecked(isTranslateEnabled); - + private void setupTranslateSection(ContentLanguagesPreference contentLanguagesPreference) { // Setup expandable advanced settings section. PreferenceCategory translationAdvancedSection = (PreferenceCategory) findPreference(TRANSLATION_ADVANCED_SECTION); @@ -173,22 +165,36 @@ translationAdvancedSection.setVisible( getPrefService().getBoolean(Pref.OFFER_TRANSLATE_ENABLED)); - // Get advanced section preference items. + // Setup target language preference. LanguageItemPickerPreference targetLanguagePreference = (LanguageItemPickerPreference) findPreference(TARGET_LANGUAGE_KEY); + targetLanguagePreference.setLanguageItem(TranslateBridge.getTargetLanguage()); + setSelectLanguageLauncher(targetLanguagePreference, + AddLanguageFragment.LANGUAGE_OPTIONS_TRANSLATE_LANGUAGES, + REQUEST_CODE_CHANGE_TARGET_LANGUAGE, + LanguagesManager.LanguageSettingsPageType.TARGET_LANGUAGE); - ChromeBasePreference alwaysTranslateLanguagesPreference = - (ChromeBasePreference) findPreference(ALWAYS_LANGUAGES_KEY); - String alwaysTranslateSummary = makeSummaryForCollection( - LanguagesManager.getInstance().getAlwaysTranslateLanguageItems()); - alwaysTranslateLanguagesPreference.setSummary(alwaysTranslateSummary); + // Setup always translate preference. + LanguageItemListPreference alwaysTranslatePreference = + (LanguageItemListPreference) findPreference(ALWAYS_LANGUAGES_KEY); + alwaysTranslatePreference.setFragmentListDelegate( + new AlwaysTranslateListFragment.ListDelegate()); + mPrefChangeRegistrar.addObserver( + Pref.PREF_ALWAYS_TRANSLATE_LIST, alwaysTranslatePreference); + setLanguageListPreferenceClickListener(alwaysTranslatePreference); + + // Setup translate switch to toggle advanced section on and off. + ChromeSwitchPreference translateSwitch = + (ChromeSwitchPreference) findPreference(TRANSLATE_SWITCH_KEY); + boolean isTranslateEnabled = getPrefService().getBoolean(Pref.OFFER_TRANSLATE_ENABLED); + translateSwitch.setChecked(isTranslateEnabled); translateSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { boolean enabled = (boolean) newValue; getPrefService().setBoolean(Pref.OFFER_TRANSLATE_ENABLED, enabled); - languageListPreference.notifyPrefChanged(); + contentLanguagesPreference.notifyPrefChanged(); translationAdvancedSection.setVisible(enabled); LanguagesManager.recordAction(enabled ? LanguagesManager.LanguageSettingsActionType .ENABLE_TRANSLATE_GLOBALLY @@ -199,18 +205,13 @@ }); translateSwitch.setManagedPreferenceDelegate((ChromeManagedPreferenceDelegate) preference -> getPrefService().isManagedPreference(Pref.OFFER_TRANSLATE_ENABLED)); - - targetLanguagePreference.setLanguageItem(TranslateBridge.getTargetLanguage()); - setSelectLanguageLauncher(targetLanguagePreference, - AddLanguageFragment.LANGUAGE_OPTIONS_TRANSLATE_LANGUAGES, - REQUEST_CODE_CHANGE_TARGET_LANGUAGE, - LanguagesManager.LanguageSettingsPageType.TARGET_LANGUAGE); } @Override public void onDetach() { super.onDetach(); LanguagesManager.recycle(); + mPrefChangeRegistrar.destroy(); } @Override @@ -239,7 +240,7 @@ /** * Overrides AddLanguageFragment.Launcher.launchAddLanguage to handle click events on the - * Add Language button inside the LanguageListPreference. + * Add Language button inside the ContentLanguagesPreference. */ @Override public void launchAddLanguage() { @@ -354,20 +355,17 @@ } /** - * Given a collection of LanguageItems return a comma separated string of the display names for - * at most the first three languages. If the list is empty return the empty string. - * @param languages List of LanguageItems. - * @return Comma sepperated string of language display names. + * Sets the PreferenceClickListener on a {@link LanguageItemListPreference} to launch an intent + * for {@link LanguageItemListFragment}. + * @param listPreference LanguageItemListPreference to set preference click listener on. */ - public static String makeSummaryForCollection(Collection<LanguageItem> languages) { - int index = 0; - ArrayList<String> languageNames = new ArrayList<String>(); - for (LanguageItem item : languages) { - if (++index > COLLECTION_SUMMARY_ITEM_LIMIT) break; - languageNames.add(item.getDisplayName()); - } - // TODO(crbug.com/1181224): Make sure to localize the separator. - return TextUtils.join(", ", languageNames); + private void setLanguageListPreferenceClickListener(LanguageItemListPreference listPreference) { + listPreference.setOnPreferenceClickListener(preference -> { + Intent intent = mSettingsLauncher.createSettingsActivityIntent( + getActivity(), listPreference.getFragmentClassName()); + startActivity(intent); + return true; + }); } @VisibleForTesting
diff --git a/chrome/browser/lite_video/lite_video_keyed_service.cc b/chrome/browser/lite_video/lite_video_keyed_service.cc index 58cfe26..bfaad5e 100644 --- a/chrome/browser/lite_video/lite_video_keyed_service.cc +++ b/chrome/browser/lite_video/lite_video_keyed_service.cc
@@ -7,7 +7,6 @@ #include "base/files/file_path.h" #include "base/metrics/histogram_macros.h" #include "base/sequenced_task_runner.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/time/default_clock.h" #include "chrome/browser/lite_video/lite_video_decider.h" @@ -41,8 +40,8 @@ {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); opt_out_store = std::make_unique<blocklist::OptOutStoreSQL>( - base::CreateSingleThreadTaskRunner({content::BrowserThread::UI}), - background_task_runner, profile_path.Append(kLiteVideoOptOutDBFilename)); + content::GetUIThreadTaskRunner({}), background_task_runner, + profile_path.Append(kLiteVideoOptOutDBFilename)); optimization_guide::OptimizationGuideDecider* opt_guide_decider = nullptr; if (lite_video::features::LiteVideoUseOptimizationGuide()) {
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc index 9667a57..0232b42 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
@@ -14,7 +14,6 @@ #include "base/bind.h" #include "base/callback.h" #include "base/feature_list.h" -#include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" @@ -42,11 +41,6 @@ typedef content::NavigationThrottle::ThrottleCheckResult ThrottleCheckResult; -const base::FeatureParam<base::TimeDelta> kManifestFetchDelay{ - &lookalikes::features::kLookalikeDigitalAssetLinks, - lookalikes::features::kLookalikeDigitalAssetLinksTimeoutParameter, - base::TimeDelta::FromSeconds(5)}; - // Returns true if |current_url| is at the end of the redirect chain // stored in |stored_redirect_chain|. bool IsInterstitialReload(const GURL& current_url, @@ -220,7 +214,8 @@ // TODO(crbug.com/1175385): Consider moving this to LookalikeURLService. digital_asset_link_validator_ = std::make_unique<DigitalAssetLinkCrossValidator>( - profile_, lookalike_origin, target_origin, kManifestFetchDelay.Get(), + profile_, lookalike_origin, target_origin, + LookalikeUrlService::kManifestFetchDelay.Get(), LookalikeUrlService::Get(profile_)->clock(), std::move(callback)); digital_asset_link_validator_->Start(); return NavigationThrottle::DEFER;
diff --git a/chrome/browser/lookalikes/lookalike_url_service.cc b/chrome/browser/lookalikes/lookalike_url_service.cc index 8e7f3c3..f3fe79d 100644 --- a/chrome/browser/lookalikes/lookalike_url_service.cc +++ b/chrome/browser/lookalikes/lookalike_url_service.cc
@@ -21,6 +21,7 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "components/lookalikes/core/features.h" #include "components/lookalikes/core/lookalike_url_util.h" #include "components/site_engagement/content/site_engagement_score.h" #include "components/site_engagement/content/site_engagement_service.h" @@ -106,6 +107,13 @@ } // namespace +// static +const base::FeatureParam<base::TimeDelta> + LookalikeUrlService::kManifestFetchDelay{ + &lookalikes::features::kLookalikeDigitalAssetLinks, + lookalikes::features::kLookalikeDigitalAssetLinksTimeoutParameter, + base::TimeDelta::FromSeconds(5)}; + LookalikeUrlService::LookalikeUrlService(Profile* profile) : profile_(profile), clock_(base::DefaultClock::GetInstance()) {}
diff --git a/chrome/browser/lookalikes/lookalike_url_service.h b/chrome/browser/lookalikes/lookalike_url_service.h index d7ab3a00..634b4ea 100644 --- a/chrome/browser/lookalikes/lookalike_url_service.h +++ b/chrome/browser/lookalikes/lookalike_url_service.h
@@ -11,6 +11,7 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/metrics/field_trial_params.h" #include "base/sequence_checker.h" #include "base/task/thread_pool.h" #include "base/time/time.h" @@ -53,6 +54,8 @@ void SetClockForTesting(base::Clock* clock); base::Clock* clock() const { return clock_; } + static const base::FeatureParam<base::TimeDelta> kManifestFetchDelay; + private: void OnUpdateEngagedSitesCompleted(std::vector<DomainInfo> new_engaged_sites);
diff --git a/chrome/browser/media/feeds/media_feeds_service.cc b/chrome/browser/media/feeds/media_feeds_service.cc index a8ed24c..75f697f 100644 --- a/chrome/browser/media/feeds/media_feeds_service.cc +++ b/chrome/browser/media/feeds/media_feeds_service.cc
@@ -10,7 +10,6 @@ #include "base/feature_list.h" #include "base/metrics/histogram_functions.h" #include "base/optional.h" -#include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/threading/thread_checker.h" #include "base/time/clock.h" @@ -181,8 +180,8 @@ } // Wrapping in PostTask is needed to avoid a crash in the tests. - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&MediaFeedsService::RecordFeedWatchtimes, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MediaFeedsService::RecordFeedWatchtimes, weak_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/media/router/test/provider_test_helpers.cc b/chrome/browser/media/router/test/provider_test_helpers.cc index 6f5dff0b..bd2b63c4 100644 --- a/chrome/browser/media/router/test/provider_test_helpers.cc +++ b/chrome/browser/media/router/test/provider_test_helpers.cc
@@ -35,7 +35,7 @@ } scoped_refptr<base::SequencedTaskRunner> MockCastAppDiscoveryService::task_runner() { - return base::CreateSingleThreadTaskRunner({content::BrowserThread::IO}); + return content::GetIOThreadTaskRunner({}); } MockDialAppDiscoveryService::MockDialAppDiscoveryService() = default;
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager.cc index 93447b6..64a541d 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/memory/ptr_util.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -112,8 +111,8 @@ base::OnceCallback<void(Args...)> reply, Args... args) { if (reply) { - base::PostTask(location, {BrowserThread::UI}, - base::BindOnce(std::move(reply), args...)); + content::GetUIThreadTaskRunner({})->PostTask( + location, base::BindOnce(std::move(reply), args...)); } }
diff --git a/chrome/browser/metrics/perf/metric_provider.cc b/chrome/browser/metrics/perf/metric_provider.cc index b58354ec9..20a49010 100644 --- a/chrome/browser/metrics/perf/metric_provider.cc +++ b/chrome/browser/metrics/perf/metric_provider.cc
@@ -7,8 +7,6 @@ #include "ash/constants/ash_features.h" #include "base/bind.h" #include "base/metrics/histogram_functions.h" -#include "base/task/post_task.h" -#include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" @@ -161,8 +159,8 @@ void MetricProvider::OnProfileDone( base::WeakPtr<MetricProvider> provider, std::unique_ptr<SampledProfile> sampled_profile) { - base::PostTask(FROM_HERE, base::TaskTraits(content::BrowserThread::UI), - base::BindOnce(&MetricProvider::AddProfileToCache, provider, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&MetricProvider::AddProfileToCache, provider, std::move(sampled_profile))); }
diff --git a/chrome/browser/notifications/notification_platform_bridge_linux.cc b/chrome/browser/notifications/notification_platform_bridge_linux.cc index 226ba19..1845d41a 100644 --- a/chrome/browser/notifications/notification_platform_bridge_linux.cc +++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc
@@ -26,7 +26,6 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "base/version.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" @@ -899,8 +898,8 @@ const base::Optional<bool>& by_user, const base::Optional<std::u16string>& reply) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); - base::PostTask( - location, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + location, base::BindOnce(ForwardNotificationOperationOnUiThread, operation, data->notification_type, data->origin_url, data->notification_id, action_index, by_user, reply,
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index ec83ed7d..3d8226b4 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -39,6 +39,7 @@ #include "chrome/browser/spellchecker/spellcheck_language_blocklist_policy_handler.h" #include "chrome/browser/spellchecker/spellcheck_language_policy_handler.h" #include "chrome/browser/ssl/secure_origin_policy_handler.h" +#include "chrome/browser/themes/theme_color_policy_handler.h" #include "chrome/browser/ui/toolbar/chrome_labs_prefs.h" #include "chrome/common/buildflags.h" #include "chrome/common/channel_info.h" @@ -1534,6 +1535,7 @@ std::make_unique<DownloadAutoOpenPolicyHandler>(chrome_schema)); handlers->AddHandler(std::make_unique<DownloadDirPolicyHandler>()); handlers->AddHandler(std::make_unique<LocalSyncPolicyHandler>()); + handlers->AddHandler(std::make_unique<ThemeColorPolicyHandler>()); handlers->AddHandler(std::make_unique<SimpleSchemaValidatingPolicyHandler>( key::kRegisteredProtocolHandlers,
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.cc b/chrome/browser/policy/messaging_layer/public/report_client.cc index 03b6704d..f55b391 100644 --- a/chrome/browser/policy/messaging_layer/public/report_client.cc +++ b/chrome/browser/policy/messaging_layer/public/report_client.cc
@@ -15,7 +15,6 @@ #include "base/memory/singleton.h" #include "base/path_service.h" #include "base/strings/strcat.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/sequence_bound.h" #include "build/chromeos_buildflags.h" @@ -175,14 +174,14 @@ scoped_refptr<InitializationStateTracker> init_state_tracker) { return new ClientInitializingContext( std::move(build_cloud_policy_client_cb_), - base::BindRepeating(&ReportingClient::BuildUploader), + base::BindRepeating(&ReportingClient::AsyncStartUploader), std::move(update_config_cb), std::move(init_complete_cb), this, init_state_tracker); } ReportingClient::ClientInitializingContext::ClientInitializingContext( GetCloudPolicyClientCallback get_client_cb, - UploaderInterface::StartCb start_upload_cb, + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb, UpdateConfigurationCallback update_config_cb, InitCompleteCallback init_complete_cb, ReportingClient* client, @@ -192,7 +191,7 @@ std::move(init_complete_cb), std::move(init_state_tracker)), get_client_cb_(std::move(get_client_cb)), - start_upload_cb_(std::move(start_upload_cb)), + async_start_upload_cb_(std::move(async_start_upload_cb)), client_(client) {} ReportingClient::ClientInitializingContext::~ClientInitializingContext() = @@ -200,8 +199,8 @@ void ReportingClient::ClientInitializingContext::OnStart() { // CloudPolicyClient requires posting to the main UI thread. - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( [](GetCloudPolicyClientCallback get_client_cb, base::OnceCallback<void(StatusOr<policy::CloudPolicyClient*>)> @@ -243,7 +242,7 @@ .set_directory(reporting_path) .set_signature_verification_public_key( SignatureVerifier::VerificationKey()), - std::move(start_upload_cb_), EncryptionModule::Create(), + std::move(async_start_upload_cb_), EncryptionModule::Create(), base::BindOnce(&ClientInitializingContext::OnStorageModuleConfigured, base::Unretained(this))); } @@ -316,15 +315,17 @@ } // static -StatusOr<std::unique_ptr<UploaderInterface>> ReportingClient::BuildUploader( +void ReportingClient::AsyncStartUploader( Priority priority, - bool need_encryption_key) { + bool need_encryption_key, + UploaderInterface::UploaderInterfaceResultCb start_uploader_cb) { ReportingClient* const instance = static_cast<ReportingClient*>(GetInstance()); DCHECK(instance->upload_client_); - return Uploader::Create(base::BindOnce( + auto uploader = Uploader::Create(base::BindOnce( &UploadClient::EnqueueUpload, base::Unretained(instance->upload_client_.get()), need_encryption_key)); + std::move(start_uploader_cb).Run(std::move(uploader)); } ReportingClient::TestEnvironment::TestEnvironment(
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.h b/chrome/browser/policy/messaging_layer/public/report_client.h index bdf0ba8..0f8435cb 100644 --- a/chrome/browser/policy/messaging_layer/public/report_client.h +++ b/chrome/browser/policy/messaging_layer/public/report_client.h
@@ -39,7 +39,7 @@ public: ClientInitializingContext( GetCloudPolicyClientCallback get_client_cb, - UploaderInterface::StartCb start_upload_cb, + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb, UpdateConfigurationCallback update_config_cb, InitCompleteCallback init_complete_cb, ReportingClient* client, @@ -73,7 +73,7 @@ StatusOr<std::unique_ptr<UploadClient>> upload_client_result); GetCloudPolicyClientCallback get_client_cb_; - UploaderInterface::StartCb start_upload_cb_; + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb_; policy::CloudPolicyClient* cloud_policy_client_ = nullptr; std::unique_ptr<UploadClient> upload_client_; @@ -125,10 +125,11 @@ void OnInitState(bool reporting_client_configured); void OnInitializationComplete(Status init_status); - // TODO(chromium:1078512) Priority is unused, remove it. - static StatusOr<std::unique_ptr<UploaderInterface>> BuildUploader( + // TODO(b/183666933) Priority is used only for testing, remove it if possible. + static void AsyncStartUploader( Priority priority, - bool need_encryption_key); + bool need_encryption_key, + UploaderInterface::UploaderInterfaceResultCb start_uploader_cb); GetCloudPolicyClientCallback build_cloud_policy_client_cb_;
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc index 59d7c554..43ed012 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc +++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
@@ -15,7 +15,6 @@ #include "base/sequenced_task_runner.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/task_runner.h" #include "base/values.h" @@ -186,8 +185,8 @@ base::Value request = std::move(request_result.value()); - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( [](policy::CloudPolicyClient* client, base::Value request, base::OnceCallback<void(base::Optional<base::Value>)>
diff --git a/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context.cc b/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context.cc index 6144247..090626c 100644 --- a/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context.cc +++ b/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context.cc
@@ -9,7 +9,6 @@ #include "base/optional.h" #include "base/sequenced_task_runner.h" #include "base/strings/string_number_conversions.h" -#include "base/task/post_task.h" #include "base/time/time.h" #include "chrome/browser/policy/dm_token_utils.h" #include "chrome/browser/profiles/profile_manager.h" @@ -64,8 +63,8 @@ } // The DMToken must be retrieved on the UI thread. - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&ReportQueueManualTestContext::GetDmToken, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ReportQueueManualTestContext::GetDmToken, base::Unretained(this))); }
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 2b9ed41..7e5971c 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
@@ -439,6 +439,10 @@ public static final String FLAGS_CACHED_TAB_GROUPS_ANDROID_ENABLED = "tab_group_android_enabled"; + /** See CachedFeatureFlags.getLastCachedMinimalBrowserFlagsTimeMillis(). */ + public static final String FLAGS_LAST_CACHED_MINIMAL_BROWSER_FLAGS_TIME_MILLIS = + "Chrome.Flags.LastCachedMinimalBrowserFlagsTimeMillis"; + public static final String FONT_USER_FONT_SCALE_FACTOR = "user_font_scale_factor"; public static final String FONT_USER_SET_FORCE_ENABLE_ZOOM = "user_set_force_enable_zoom"; @@ -936,6 +940,7 @@ FIRST_RUN_SKIPPED_BY_POLICY, FLAGS_CACHED.pattern(), FLAGS_FIELD_TRIAL_PARAM_CACHED.pattern(), + FLAGS_LAST_CACHED_MINIMAL_BROWSER_FLAGS_TIME_MILLIS, HOMEPAGE_LOCATION_POLICY, HOMEPAGE_USE_CHROME_NTP, IMAGE_DESCRIPTIONS_JUST_ONCE_COUNT,
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index 3cff6d2..4743a6e 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc
@@ -11,7 +11,6 @@ #include "base/callback_helpers.h" #include "base/location.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" @@ -600,8 +599,8 @@ bool PrintJob::PostTask(const base::Location& from_here, base::OnceClosure task) { - return base::PostTask(from_here, {content::BrowserThread::UI}, - std::move(task)); + return content::GetUIThreadTaskRunner({})->PostTask(from_here, + std::move(task)); } void PrintJob::HoldUntilStopIsCalled() {
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc index 956db0ba..b34730f 100644 --- a/chrome/browser/printing/printer_query.cc +++ b/chrome/browser/printing/printer_query.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/location.h" -#include "base/task/post_task.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" @@ -170,8 +169,8 @@ bool PrinterQuery::PostTask(const base::Location& from_here, base::OnceClosure task) { - return base::PostTask(from_here, {content::BrowserThread::IO}, - std::move(task)); + return content::GetIOThreadTaskRunner({})->PostTask(from_here, + std::move(task)); } bool PrinterQuery::is_valid() const {
diff --git a/chrome/browser/query_tiles/tile_service_factory.cc b/chrome/browser/query_tiles/tile_service_factory.cc index 734ecb0..2a669ac5 100644 --- a/chrome/browser/query_tiles/tile_service_factory.cc +++ b/chrome/browser/query_tiles/tile_service_factory.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/memory/singleton.h" +#include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/image_fetcher/image_fetcher_service_factory.h" #include "chrome/browser/net/system_network_context_manager.h" @@ -27,6 +28,13 @@ #include "google_apis/google_api_keys.h" #include "services/network/public/cpp/shared_url_loader_factory.h" +#if defined(OS_ANDROID) +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "chrome/android/chrome_jni_headers/TileServiceUtils_jni.h" +#endif + namespace query_tiles { namespace { @@ -115,10 +123,18 @@ version.components()[3], // Patch channel_name.c_str()); + std::string default_server_url; +#if defined(OS_ANDROID) + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> j_server_url = + Java_TileServiceUtils_getDefaultServerUrl(env); + default_server_url = + base::android::ConvertJavaStringToUTF8(env, j_server_url); +#endif return CreateTileService(image_fetcher_service, db_provider, storage_dir, background_task_scheduler, accept_languanges, GetCountryCode(), GetGoogleAPIKey(), client_version, - url_loader_factory, + default_server_url, url_loader_factory, ProfileKey::FromSimpleFactoryKey(key)->GetPrefs()); }
diff --git a/chrome/browser/reputation/reputation_web_contents_observer.cc b/chrome/browser/reputation/reputation_web_contents_observer.cc index c1067bb..b781b107 100644 --- a/chrome/browser/reputation/reputation_web_contents_observer.cc +++ b/chrome/browser/reputation/reputation_web_contents_observer.cc
@@ -11,9 +11,11 @@ #include "base/metrics/histogram_macros.h" #include "base/optional.h" #include "build/build_config.h" +#include "chrome/browser/lookalikes/lookalike_url_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/reputation/reputation_service.h" #include "chrome/browser/reputation/safety_tip_ui.h" +#include "components/lookalikes/core/features.h" #include "components/lookalikes/core/lookalike_url_util.h" #include "components/security_state/core/features.h" #include "components/security_state/core/security_state.h" @@ -394,14 +396,58 @@ return; } + if (!base::FeatureList::IsEnabled( + lookalikes::features::kLookalikeDigitalAssetLinks) || + !result.suggested_url.is_valid()) { + RecordPostFlagCheckHistogram(result.safety_tip_status); + ShowSafetyTipDialog( + web_contents(), result.safety_tip_status, result.suggested_url, + base::BindOnce(OnSafetyTipClosed, result, base::Time::Now(), + navigation_source_id, profile_, result.url, + result.safety_tip_status, + std::move(safety_tip_close_callback_for_testing_))); + MaybeCallReputationCheckCallback(true); + return; + } + + const url::Origin lookalike_origin = url::Origin::Create(result.url); + const url::Origin target_origin = url::Origin::Create(result.suggested_url); + + DigitalAssetLinkCrossValidator::ResultCallback callback = base::BindOnce( + &ReputationWebContentsObserver::OnDigitalAssetLinkValidationResult, + weak_factory_.GetWeakPtr(), result, navigation_source_id); + digital_asset_link_validator_ = + std::make_unique<DigitalAssetLinkCrossValidator>( + profile_, lookalike_origin, target_origin, + LookalikeUrlService::kManifestFetchDelay.Get(), + LookalikeUrlService::Get(profile_)->clock(), std::move(callback)); + digital_asset_link_validator_->Start(); +} + +void ReputationWebContentsObserver::OnDigitalAssetLinkValidationResult( + ReputationCheckResult result, + ukm::SourceId navigation_source_id, + bool validation_succeeded) { + if (validation_succeeded) { + // Don't show a safety tip dialog. + base::UmaHistogramEnumeration( + "Security.SafetyTips.ReputationCheckComplete.DidFinishNavigation", + security_state::SafetyTipStatus::kDigitalAssetLinkMatch); + RecordPostFlagCheckHistogram( + security_state::SafetyTipStatus::kDigitalAssetLinkMatch); + MaybeCallReputationCheckCallback(/*heuristics_checked=*/true); + return; + } + RecordPostFlagCheckHistogram(result.safety_tip_status); + ShowSafetyTipDialog( web_contents(), result.safety_tip_status, result.suggested_url, base::BindOnce(OnSafetyTipClosed, result, base::Time::Now(), navigation_source_id, profile_, result.url, result.safety_tip_status, std::move(safety_tip_close_callback_for_testing_))); - MaybeCallReputationCheckCallback(true); + MaybeCallReputationCheckCallback(/*heuristics_checked=*/true); } void ReputationWebContentsObserver::MaybeCallReputationCheckCallback(
diff --git a/chrome/browser/reputation/reputation_web_contents_observer.h b/chrome/browser/reputation/reputation_web_contents_observer.h index d711850c..291e31f 100644 --- a/chrome/browser/reputation/reputation_web_contents_observer.h +++ b/chrome/browser/reputation/reputation_web_contents_observer.h
@@ -7,6 +7,7 @@ #include "base/callback_forward.h" #include "base/optional.h" +#include "chrome/browser/lookalikes/digital_asset_links_cross_validator.h" #include "chrome/browser/reputation/reputation_service.h" #include "chrome/browser/reputation/safety_tip_ui.h" #include "components/security_state/core/security_state.h" @@ -87,6 +88,10 @@ ReputationCheckResult result, ukm::SourceId navigation_source_id); + void OnDigitalAssetLinkValidationResult(ReputationCheckResult result, + ukm::SourceId navigation_source_id, + bool validation_succeeded); + Profile* profile_; // Used to cache the last safety tip info (and associated navigation entry ID) @@ -108,6 +113,8 @@ base::OnceClosure safety_tip_close_callback_for_testing_; + std::unique_ptr<DigitalAssetLinkCrossValidator> digital_asset_link_validator_; + base::WeakPtrFactory<ReputationWebContentsObserver> weak_factory_{this}; WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/chrome/browser/reputation/safety_tip_ui_helper.cc b/chrome/browser/reputation/safety_tip_ui_helper.cc index 8bb7356..4240fe4 100644 --- a/chrome/browser/reputation/safety_tip_ui_helper.cc +++ b/chrome/browser/reputation/safety_tip_ui_helper.cc
@@ -79,6 +79,7 @@ IDS_PAGE_INFO_SAFETY_TIP_LOOKALIKE_TITLE, security_interstitials::common_string_util::GetFormattedHostName( suggested_url)); + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kBadReputationIgnored: case security_state::SafetyTipStatus::kLookalikeIgnored: case security_state::SafetyTipStatus::kBadKeyword: @@ -98,6 +99,7 @@ case security_state::SafetyTipStatus::kBadReputation: case security_state::SafetyTipStatus::kLookalike: return l10n_util::GetStringUTF16(IDS_PAGE_INFO_SAFETY_TIP_DESCRIPTION); + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kBadReputationIgnored: case security_state::SafetyTipStatus::kLookalikeIgnored: case security_state::SafetyTipStatus::kBadKeyword: @@ -115,6 +117,7 @@ return IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_LEAVE_BUTTON; case security_state::SafetyTipStatus::kLookalike: return IDS_PAGE_INFO_SAFETY_TIP_LOOKALIKE_LEAVE_BUTTON; + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kBadReputationIgnored: case security_state::SafetyTipStatus::kLookalikeIgnored: case security_state::SafetyTipStatus::kBadKeyword:
diff --git a/chrome/browser/resources/bookmarks/BUILD.gn b/chrome/browser/resources/bookmarks/BUILD.gn index c283afe..ecb4ec8 100644 --- a/chrome/browser/resources/bookmarks/BUILD.gn +++ b/chrome/browser/resources/bookmarks/BUILD.gn
@@ -189,7 +189,7 @@ ":store", ":store_client", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements:find_shortcut_behavior.m", + "//ui/webui/resources/cr_elements:find_shortcut_behavior", "//ui/webui/resources/cr_elements/cr_splitter:cr_splitter", "//ui/webui/resources/js:load_time_data.m", ]
diff --git a/chrome/browser/resources/bookmarks/app.js b/chrome/browser/resources/bookmarks/app.js index 456d71a0..dd1e2832 100644 --- a/chrome/browser/resources/bookmarks/app.js +++ b/chrome/browser/resources/bookmarks/app.js
@@ -14,7 +14,7 @@ import './strings.m.js'; import './toolbar.js'; -import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.m.js'; +import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index 98783d2..f1d5f1f 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -482,6 +482,7 @@ "$externs_path/login_state.js", "$externs_path/metrics_private.js", "$externs_path/settings_private.js", + "$externs_path/tts.js", "$externs_path/virtual_keyboard_private.js", ] }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/locale_output_helper.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/locale_output_helper.js index 7344a16..1b18191e 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/locale_output_helper.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/locale_output_helper.js
@@ -31,7 +31,7 @@ * @private {number} */ LocaleOutputHelper.PROBABILITY_THRESHOLD_ = 0.9; - /** @private {!Array<!TtsVoice>} */ + /** @private {!Array<!chrome.tts.TtsVoice>} */ this.availableVoices_ = []; const setAvailableVoices = () => { chrome.tts.getVoices((voices) => {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/tts_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/tts_background.js index 0f7eb2c..010072c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/tts_background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/tts_background.js
@@ -419,7 +419,7 @@ this.onTtsEvent_(event, utteranceId); }, this); - const validatedProperties = {}; + const validatedProperties = /** @type {!chrome.tts.TtsOptions} */ ({}); for (let i = 0; i < TtsBackground.ALLOWED_PROPERTIES_.length; i++) { const p = TtsBackground.ALLOWED_PROPERTIES_[i]; if (utterance.properties[p]) {
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn index 4e7d0010..ca2e018 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn
@@ -165,10 +165,10 @@ externs_list = [ "$externs_path/accessibility_private.js", "$externs_path/automation.js", - "$externs_path/chrome_extensions.js", "$externs_path/clipboard.js", "$externs_path/command_line_private.js", "$externs_path/pending.js", + "$externs_path/tts.js", ] } @@ -177,8 +177,8 @@ externs_list = [ "$externs_path/accessibility_private.js", "$externs_path/automation.js", - "$externs_path/chrome_extensions.js", "$externs_path/metrics_private.js", + "$externs_path/tts.js", ] } @@ -212,7 +212,6 @@ externs_list = [ "$externs_path/accessibility_private.js", "$externs_path/automation.js", - "$externs_path/chrome_extensions.js", ] } @@ -226,7 +225,10 @@ js_library("metrics_utils") { deps = [ ":prefs_manager" ] - externs_list = [ "$externs_path/metrics_private.js" ] + externs_list = [ + "$externs_path/metrics_private.js", + "$externs_path/tts.js", + ] } js_library("select_to_speak_constants") {
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/prefs_manager.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/prefs_manager.js index b49af183..d72cf31d27 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/prefs_manager.js +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/prefs_manager.js
@@ -57,13 +57,15 @@ } voices.forEach((voice) => { - if (!voice.eventTypes.includes('start') || - !voice.eventTypes.includes('end') || - !voice.eventTypes.includes('word') || - !voice.eventTypes.includes('cancelled')) { + if (!voice.eventTypes.includes(chrome.tts.EventType.START) || + !voice.eventTypes.includes(chrome.tts.EventType.END) || + !voice.eventTypes.includes(chrome.tts.EventType.WORD) || + !voice.eventTypes.includes(chrome.tts.EventType.CANCELLED)) { return; } - this.validVoiceNames_.add(voice.voiceName); + if (voice.voiceName) { + this.validVoiceNames_.add(voice.voiceName); + } }); voices.sort(function(a, b) { @@ -84,7 +86,10 @@ return score(b) - score(a); }); - this.voiceNameFromLocale_ = voices[0].voiceName; + const firstVoiceName = voices[0].voiceName; + if (firstVoiceName) { + this.voiceNameFromLocale_ = firstVoiceName; + } chrome.storage.sync.get(['voice'], (prefs) => { if (!prefs['voice']) { @@ -271,10 +276,10 @@ /** * Generates the basic speech options for Select-to-Speak based on user * preferences. Call for each chrome.tts.speak. - * @return {!TtsOptions} options The TTS options. + * @return {!chrome.tts.TtsOptions} options The TTS options. */ speechOptions() { - const options = {enqueue: true}; + const options = /** @type {!chrome.tts.TtsOptions} */ ({enqueue: true}); // To use the default (system) voice: don't specify options['voiceName']. if (this.voiceNameFromPrefs_ === PrefsManager.SYSTEM_VOICE) {
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js index d8514b69..2c74859 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js
@@ -1095,7 +1095,7 @@ if (!nodeGroup) { return; } - const options = {}; + const options = /** @type {!chrome.tts.TtsOptions} */ ({}); // Copy options so we can add lang below Object.assign(options, this.prefsManager_.speechOptions()); if (this.enableLanguageDetectionIntegration_ && @@ -1297,21 +1297,25 @@ /** * Uses the 'word' speech event to determine which node is currently beings * spoken, and prepares for highlight if enabled. - * @param {!TtsEvent} event The event to use for updates. + * @param {!chrome.tts.TtsEvent} event The event to use for updates. * @param {ParagraphUtils.NodeGroup} nodeGroup The node group for this * utterance. * @private */ onTtsWordEvent_(event, nodeGroup) { + if (event.charIndex === undefined) { + return; + } // Not all speech engines include length in the ttsEvent object. . const hasLength = event.length !== undefined && event.length >= 0; + const length = event.length || 0; // Only update the |this.currentCharIndex_| if event has a higher charIndex. // TTS sometimes will report an incorrect number at the end of an utterance. this.currentCharIndex_ = Math.max(event.charIndex, this.currentCharIndex_); console.debug(nodeGroup.text + ' (index ' + event.charIndex + ')'); let debug = '-'.repeat(event.charIndex); if (hasLength) { - debug += '^'.repeat(event.length); + debug += '^'.repeat(length); } else { debug += '^'; } @@ -1333,8 +1337,7 @@ if (hasLength) { this.currentNodeWord_ = { 'start': event.charIndex - this.currentNodeGroupItem_.startChar, - 'end': event.charIndex + event.length - - this.currentNodeGroupItem_.startChar + 'end': event.charIndex + length - this.currentNodeGroupItem_.startChar }; this.updateUi_(); } else {
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_options.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_options.js index 378c980..35effd1 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_options.js +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_options.js
@@ -112,16 +112,16 @@ voice.voiceName = voice.voiceName || ''; }); voices.sort(function(a, b) { - return a.voiceName.localeCompare(b.voiceName); + return a.voiceName.localeCompare(b.voiceName || ''); }); voices.forEach(function(voice) { if (!voice.voiceName) { return; } - if (!voice.eventTypes.includes('start') || - !voice.eventTypes.includes('end') || - !voice.eventTypes.includes('word') || - !voice.eventTypes.includes('cancelled')) { + if (!voice.eventTypes.includes(chrome.tts.EventType.START) || + !voice.eventTypes.includes(chrome.tts.EventType.END) || + !voice.eventTypes.includes(chrome.tts.EventType.WORD) || + !voice.eventTypes.includes(chrome.tts.EventType.CANCELLED)) { // Required event types for Select-to-Speak. return; }
diff --git a/chrome/browser/resources/downloads/BUILD.gn b/chrome/browser/resources/downloads/BUILD.gn index 37cf13c..5db69be 100644 --- a/chrome/browser/resources/downloads/BUILD.gn +++ b/chrome/browser/resources/downloads/BUILD.gn
@@ -183,7 +183,7 @@ ":search_service", ":toolbar", "//third_party/polymer/v3_0/components-chromium/iron-list", - "//ui/webui/resources/cr_elements:find_shortcut_behavior.m", + "//ui/webui/resources/cr_elements:find_shortcut_behavior", "//ui/webui/resources/cr_elements/cr_toast:cr_toast_manager.m", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:load_time_data.m",
diff --git a/chrome/browser/resources/downloads/manager.js b/chrome/browser/resources/downloads/manager.js index e5fcca8..adb7790 100644 --- a/chrome/browser/resources/downloads/manager.js +++ b/chrome/browser/resources/downloads/manager.js
@@ -14,7 +14,7 @@ import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import {getToastManager} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.m.js'; -import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.m.js'; +import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
diff --git a/chrome/browser/resources/history/BUILD.gn b/chrome/browser/resources/history/BUILD.gn index 9bd188a..619f3692 100644 --- a/chrome/browser/resources/history/BUILD.gn +++ b/chrome/browser/resources/history/BUILD.gn
@@ -207,7 +207,7 @@ ":synced_device_card", ":synced_device_manager", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements:find_shortcut_behavior.m", + "//ui/webui/resources/cr_elements:find_shortcut_behavior", "//ui/webui/resources/cr_elements/cr_drawer:cr_drawer", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:web_ui_listener_behavior.m",
diff --git a/chrome/browser/resources/history/app.js b/chrome/browser/resources/history/app.js index 6308172..73fe4a0f 100644 --- a/chrome/browser/resources/history/app.js +++ b/chrome/browser/resources/history/app.js
@@ -13,7 +13,7 @@ import './shared_style.js'; import './strings.m.js'; -import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.m.js'; +import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.html index 4954750..944bc0a2 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.html
@@ -107,6 +107,24 @@ deep-link-focus-id$="[[Setting.kSwitchActionAutoScanKeyboard]]"> </settings-slider> </div> + <template is="dom-if" + if="[[isSwitchAccessPointScanningEnabled_]]" restamp> + <div class="settings-box continuation list-item"> + <div class="start sub-item settings-box-text" id="pointScanSpeed" + aria-hidden="true"> + $i18n{switchAccessPointScanSpeedLabel} + </div> + <settings-slider id="pointScanSpeedSlider" + pref="{{prefs.settings.a11y.switch_access.point_scan.speed_dips_per_second}}" + ticks="[[pointScanSpeedRangeDipsPerSecond_]]" + min="[[minPointScanSpeed_]]" + max="[[maxPointScanSpeed_]]" + label-aria="$i18n{switchAccessPointScanSpeedLabel}" + label-min="[[minPointScanSpeed_]]" + label-max="[[maxPointScanSpeed_]]"> + </settings-slider> + </div> + </template> </div> </template> <script src="switch_access_subpage.js"></script>
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.js index 2903bb55..2250421 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.js +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.js
@@ -20,6 +20,9 @@ 1600, 1500, 1400, 1300, 1200, 1100, 1000, 900, 800, 700 ]; +/** @type {!Array<number>} */ +const POINT_SCAN_SPEED_RANGE_DIPS_PER_SECOND = [25, 50, 75, 100, 150, 200, 300]; + /** * @param {!Array<number>} ticksInMs * @return {!Array<!cr_slider.SliderTick>} @@ -29,6 +32,14 @@ return ticksInMs.map(x => ({label: `${x / 1000}`, value: x})); } +/** + * @param {!Array<number>} ticks + * @return {!Array<!cr_slider.SliderTick>} + */ +function ticksWithCountingLabels(ticks) { + return ticks.map((x, i) => ({label: i + 1, value: x})); +} + Polymer({ is: 'settings-switch-access-subpage', @@ -77,6 +88,13 @@ value: ticksWithLabelsInSec(AUTO_SCAN_SPEED_RANGE_MS), }, + /** @private {Array<number>} */ + pointScanSpeedRangeDipsPerSecond_: { + readOnly: true, + type: Array, + value: ticksWithCountingLabels(POINT_SCAN_SPEED_RANGE_DIPS_PER_SECOND), + }, + /** @private {Object} */ formatter_: { type: Object, @@ -117,6 +135,16 @@ }, }, + /** @private {number} */ + maxPointScanSpeed_: { + readOnly: true, + type: Number, + value: POINT_SCAN_SPEED_RANGE_DIPS_PER_SECOND.length + }, + + /** @private {number} */ + minPointScanSpeed_: {readOnly: true, type: Number, value: 1}, + /** * Used by DeepLinkingBehavior to focus this page's deep links. * @type {!Set<!chromeos.settings.mojom.Setting>} @@ -290,6 +318,14 @@ }, /** + * @return {boolean} Whether Switch Access point scanning is enabled. + * @private + */ + isSwitchAccessPointScanningEnabled_() { + return loadTimeData.getBoolean('isSwitchAccessPointScanningEnabled'); + }, + + /** * @param {number} scanSpeedValueMs * @return {string} a string representing the scan speed in seconds. * @private
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn index 297d8aa..aa885cd0 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
@@ -98,7 +98,7 @@ "../../languages_page:languages", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements:cr_scrollable_behavior.m", - "//ui/webui/resources/cr_elements:find_shortcut_behavior.m", + "//ui/webui/resources/cr_elements:find_shortcut_behavior", "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field", ] extra_deps = [ ":os_add_languages_dialog_module" ]
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 02bd6ebb..4b97d7120 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -332,9 +332,10 @@ "chrome/browser/resources/settings/settings_shared_css.html", "chrome/browser/resources/settings/settings_vars_css.html", "ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html", - "ui/webui/resources/cr_elements/cr_tabs/cr_tabs.html", "ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html", "ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html", + "ui/webui/resources/cr_elements/cr_tabs/cr_tabs.html", "ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html", + "ui/webui/resources/cr_elements/find_shortcut_behavior.html", "ui/webui/resources/html/plural_string_proxy.html", ]
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn index b1fd1127..a2b8f53 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn
@@ -26,7 +26,7 @@ "../os_toolbar:os_toolbar.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements:cr_container_shadow_behavior.m", - "//ui/webui/resources/cr_elements:find_shortcut_behavior.m", + "//ui/webui/resources/cr_elements:find_shortcut_behavior", "//ui/webui/resources/cr_elements/cr_drawer:cr_drawer", "//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior.m", "//ui/webui/resources/js:assert.m",
diff --git a/chrome/browser/resources/settings/languages_page/BUILD.gn b/chrome/browser/resources/settings/languages_page/BUILD.gn index 7752522..6b0e3218 100644 --- a/chrome/browser/resources/settings/languages_page/BUILD.gn +++ b/chrome/browser/resources/settings/languages_page/BUILD.gn
@@ -31,7 +31,7 @@ ":languages_types", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements:cr_scrollable_behavior.m", - "//ui/webui/resources/cr_elements:find_shortcut_behavior.m", + "//ui/webui/resources/cr_elements:find_shortcut_behavior", "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field", ] }
diff --git a/chrome/browser/resources/settings/languages_page/add_languages_dialog.js b/chrome/browser/resources/settings/languages_page/add_languages_dialog.js index 62426655..9cec8621 100644 --- a/chrome/browser/resources/settings/languages_page/add_languages_dialog.js +++ b/chrome/browser/resources/settings/languages_page/add_languages_dialog.js
@@ -15,7 +15,7 @@ import '../settings_shared_css.js'; import {CrScrollableBehavior} from 'chrome://resources/cr_elements/cr_scrollable_behavior.m.js'; -import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.m.js'; +import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; Polymer({
diff --git a/chrome/browser/resources/settings/languages_page/languages.js b/chrome/browser/resources/settings/languages_page/languages.js index 604d1f09..8a4f04a 100644 --- a/chrome/browser/resources/settings/languages_page/languages.js +++ b/chrome/browser/resources/settings/languages_page/languages.js
@@ -189,6 +189,8 @@ 'prefs.spellcheck.blocked_dictionaries.value.*, languages)', 'translateLanguagesPrefChanged_(' + 'prefs.translate_blocked_languages.value.*, languages)', + 'translateTargetPrefChanged_(' + + 'prefs.translate_recent_target.value, languages)', 'updateRemovableLanguages_(' + 'prefs.intl.app_locale.value, languages.enabled)', 'updateRemovableLanguages_(' + @@ -544,6 +546,16 @@ } }, + /** @private */ + translateTargetPrefChanged_() { + if (this.prefs === undefined || this.languages === undefined) { + return; + } + this.set( + 'languages.translateTarget', + this.getPref('translate_recent_target').value); + }, + /** * Constructs the languages model. * @param {!ModelArgs} args used to populate the model @@ -1011,6 +1023,15 @@ }, /** + * Sets the translate target language and adds it to the content languages if + * not already there. + * @param {string} languageCode + */ + setTranslateTargetLanguage(languageCode) { + this.languageSettingsPrivate_.setTranslateTargetLanguage(languageCode); + }, + + /** * Enables or disables spell check for the given language. * @param {string} languageCode * @param {boolean} enable
diff --git a/chrome/browser/resources/settings/settings_page/BUILD.gn b/chrome/browser/resources/settings/settings_page/BUILD.gn index 2fc8d822..f1bffe2 100644 --- a/chrome/browser/resources/settings/settings_page/BUILD.gn +++ b/chrome/browser/resources/settings/settings_page/BUILD.gn
@@ -51,7 +51,7 @@ "..:setting_id_param_util", "//third_party/polymer/v3_0/components-chromium/iron-resizable-behavior:iron-resizable-behavior", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements:find_shortcut_behavior.m", + "//ui/webui/resources/cr_elements:find_shortcut_behavior", "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:i18n_behavior.m",
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.js b/chrome/browser/resources/settings/settings_page/settings_subpage.js index b640c5f..11576393 100644 --- a/chrome/browser/resources/settings/settings_page/settings_subpage.js +++ b/chrome/browser/resources/settings/settings_page/settings_subpage.js
@@ -15,7 +15,7 @@ import '//resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; import '../settings_shared_css.js'; -import {FindShortcutBehavior} from '//resources/cr_elements/find_shortcut_behavior.m.js'; +import {FindShortcutBehavior} from '//resources/cr_elements/find_shortcut_behavior.js'; import {assert} from '//resources/js/assert.m.js'; import {focusWithoutInk} from '//resources/js/cr/ui/focus_without_ink.m.js'; import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
diff --git a/chrome/browser/resources/settings/settings_ui/BUILD.gn b/chrome/browser/resources/settings/settings_ui/BUILD.gn index 7176d78..471c487 100644 --- a/chrome/browser/resources/settings/settings_ui/BUILD.gn +++ b/chrome/browser/resources/settings/settings_ui/BUILD.gn
@@ -24,7 +24,7 @@ "../settings_menu:settings_menu", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements:cr_container_shadow_behavior.m", - "//ui/webui/resources/cr_elements:find_shortcut_behavior.m", + "//ui/webui/resources/cr_elements:find_shortcut_behavior", "//ui/webui/resources/cr_elements/cr_drawer:cr_drawer", "//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar", "//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar_search_field",
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js index f6382e8..c8e2c8c 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -24,7 +24,7 @@ import '../settings_vars_css.js'; import {CrContainerShadowBehavior} from 'chrome://resources/cr_elements/cr_container_shadow_behavior.m.js'; -import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.m.js'; +import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {isChromeOS} from 'chrome://resources/js/cr.m.js'; import {listenOnce} from 'chrome://resources/js/util.m.js';
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js index 10a0940..698d8edd 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js +++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js
@@ -322,6 +322,7 @@ info: { chromeThemeId: this.profileThemeInfo.colorId, }, + isForced: false, }; },
diff --git a/chrome/browser/sharing/fake_device_info.cc b/chrome/browser/sharing/fake_device_info.cc index 5e8e161..3d0e5f7a 100644 --- a/chrome/browser/sharing/fake_device_info.cc +++ b/chrome/browser/sharing/fake_device_info.cc
@@ -19,6 +19,7 @@ manufacturer_name, model_name, last_updated_timestamp, syncer::DeviceInfoUtil::GetPulseInterval(), /*send_tab_to_self_receiving_enabled=*/false, sharing_info, + /*paask_info=*/base::nullopt, /*fcm_registration_token=*/std::string(), /*interested_data_types=*/syncer::ModelTypeSet()); }
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.cc b/chrome/browser/signin/dice_web_signin_interceptor.cc index b266430..1645c50 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor.cc
@@ -554,11 +554,17 @@ DCHECK(interception_bubble_handle_); interception_bubble_handle_.reset(); // Close the bubble now. session_startup_helper_.reset(); - if (is_new_profile && !profile_->IsEphemeralGuestProfile()) { - Browser* browser = chrome::FindBrowserWithProfile(profile_); - DCHECK(browser); - delegate_->ShowProfileCustomizationBubble(browser); - } + + if (!is_new_profile || profile_->IsEphemeralGuestProfile()) + return; + + // Don't show the customization bubble if a valid policy theme is set. + if (ThemeServiceFactory::GetForProfile(profile_)->UsingPolicyTheme()) + return; + + Browser* browser = chrome::FindBrowserWithProfile(profile_); + DCHECK(browser); + delegate_->ShowProfileCustomizationBubble(browser); } // static
diff --git a/chrome/browser/speech/speech_recognition_service_browsertest.cc b/chrome/browser/speech/speech_recognition_service_browsertest.cc index ee2ebb7..b9808e1 100644 --- a/chrome/browser/speech/speech_recognition_service_browsertest.cc +++ b/chrome/browser/speech/speech_recognition_service_browsertest.cc
@@ -219,7 +219,7 @@ &is_multichannel_supported, run_loop.get())); run_loop->Run(); - ASSERT_TRUE(is_multichannel_supported); + ASSERT_FALSE(is_multichannel_supported); } void SpeechRecognitionServiceTest::LaunchServiceWithAudioSourceFetcher() {
diff --git a/chrome/browser/sync/device_info_sync_service_factory.cc b/chrome/browser/sync/device_info_sync_service_factory.cc index a15ab94..687b18a 100644 --- a/chrome/browser/sync/device_info_sync_service_factory.cc +++ b/chrome/browser/sync/device_info_sync_service_factory.cc
@@ -32,6 +32,10 @@ #include "components/sync_device_info/device_info_sync_service_impl.h" #include "components/sync_device_info/local_device_info_provider_impl.h" +#if defined(OS_ANDROID) +#include "chrome/browser/webauthn/android/cable_module_android.h" +#endif + namespace { class DeviceInfoSyncClient : public syncer::DeviceInfoSyncClient { @@ -97,6 +101,15 @@ return syncer::ModelTypeSet(); } + base::Optional<syncer::DeviceInfo::PhoneAsASecurityKeyInfo> + GetPhoneAsASecurityKeyInfo() const override { +#if defined(OS_ANDROID) + return webauthn::authenticator::GetSyncDataIfRegistered(); +#else + return base::nullopt; +#endif + } + private: Profile* const profile_; };
diff --git a/chrome/browser/themes/theme_color_policy_handler.cc b/chrome/browser/themes/theme_color_policy_handler.cc new file mode 100644 index 0000000..4c88df6 --- /dev/null +++ b/chrome/browser/themes/theme_color_policy_handler.cc
@@ -0,0 +1,71 @@ +// 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/themes/theme_color_policy_handler.h" + +#include "base/strings/string_number_conversions.h" +#include "base/values.h" +#include "build/build_config.h" +#include "chrome/common/pref_names.h" +#include "components/policy/core/browser/policy_error_map.h" +#include "components/policy/policy_constants.h" +#include "components/prefs/pref_value_map.h" +#include "components/strings/grit/components_strings.h" +#include "third_party/re2/src/re2/re2.h" +#include "third_party/skia/include/core/SkColor.h" + +namespace { + +// Check if the given string is a valid hex color. +bool IsValidHexColor(const std::string& input) { + // A valid hex color must be of form "#RRGGBB" ("#" is optional). + // Support for "RGB" may be added in the future. + return RE2::FullMatch(input, "^#?[0-9a-fA-F]{6}$"); +} + +// Convert valid hex string to corresponding SkColor. +SkColor HexToSkColor(const std::string& hex_color) { + DCHECK(!hex_color.empty()); + DCHECK(IsValidHexColor(hex_color)); + + const int kHexColorLength = 6; + int color; + // A valid hex color may or may not have "#" as the first character. + base::HexStringToInt( + hex_color.substr(hex_color[0] == '#' ? 1 : 0, kHexColorLength), &color); + return SkColorSetA(color, SK_AlphaOPAQUE); +} + +} // namespace + +ThemeColorPolicyHandler::ThemeColorPolicyHandler() + : TypeCheckingPolicyHandler(policy::key::kBrowserThemeColor, + base::Value::Type::STRING) {} + +ThemeColorPolicyHandler::~ThemeColorPolicyHandler() = default; + +bool ThemeColorPolicyHandler::CheckPolicySettings( + const policy::PolicyMap& policies, + policy::PolicyErrorMap* errors) { + const base::Value* value = nullptr; + if (!CheckAndGetValue(policies, errors, &value)) + return false; + + if (value && !IsValidHexColor(value->GetString())) { + errors->AddError(policy_name(), IDS_POLICY_HEX_COLOR_ERROR, + value->GetString()); + return false; + } + return true; +} + +void ThemeColorPolicyHandler::ApplyPolicySettings( + const policy::PolicyMap& policies, + PrefValueMap* prefs) { + const base::Value* value = policies.GetValue(policy_name()); + if (!value) + return; + + prefs->SetInteger(prefs::kPolicyThemeColor, HexToSkColor(value->GetString())); +}
diff --git a/chrome/browser/themes/theme_color_policy_handler.h b/chrome/browser/themes/theme_color_policy_handler.h new file mode 100644 index 0000000..51626d82e --- /dev/null +++ b/chrome/browser/themes/theme_color_policy_handler.h
@@ -0,0 +1,27 @@ +// 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_THEMES_THEME_COLOR_POLICY_HANDLER_H_ +#define CHROME_BROWSER_THEMES_THEME_COLOR_POLICY_HANDLER_H_ + +#include <string> + +#include "components/policy/core/browser/configuration_policy_handler.h" + +// ConfigurationPolicyHandler for the BrowserThemeColor policy. +class ThemeColorPolicyHandler : public policy::TypeCheckingPolicyHandler { + public: + ThemeColorPolicyHandler(); + ThemeColorPolicyHandler(const ThemeColorPolicyHandler&) = delete; + ThemeColorPolicyHandler& operator=(const ThemeColorPolicyHandler&) = delete; + ~ThemeColorPolicyHandler() override; + + // policy::TypeCheckingPolicyHandler: + bool CheckPolicySettings(const policy::PolicyMap& policies, + policy::PolicyErrorMap* errors) override; + void ApplyPolicySettings(const policy::PolicyMap& policies, + PrefValueMap* prefs) override; +}; + +#endif // CHROME_BROWSER_THEMES_THEME_COLOR_POLICY_HANDLER_H_
diff --git a/chrome/browser/themes/theme_color_policy_handler_unittest.cc b/chrome/browser/themes/theme_color_policy_handler_unittest.cc new file mode 100644 index 0000000..d02d596 --- /dev/null +++ b/chrome/browser/themes/theme_color_policy_handler_unittest.cc
@@ -0,0 +1,105 @@ +// 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/themes/theme_color_policy_handler.h" + +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "chrome/common/pref_names.h" +#include "components/policy/core/browser/policy_error_map.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/core/common/policy_types.h" +#include "components/policy/policy_constants.h" +#include "components/prefs/pref_value_map.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkColor.h" + +namespace policy { + +class ThemeColorPolicyHandlerTest : public testing::Test { + protected: + void SetPolicy(base::Value value) { + policies_.Set(key::kBrowserThemeColor, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, std::move(value), + nullptr); + } + + bool CheckPolicy(base::Value value) { + SetPolicy(std::move(value)); + return handler_.CheckPolicySettings(policies_, &errors_); + } + + void ApplyPolicies() { handler_.ApplyPolicySettings(policies_, &prefs_); } + + void CheckValidPolicy(const std::string& policy_value, + SkColor expected_color) { + ASSERT_FALSE(policy_value.empty()); + base::Value theme_color_value(std::move(policy_value)); + EXPECT_FALSE(theme_color_value.GetString().empty()); + EXPECT_TRUE(CheckPolicy(theme_color_value.Clone())); + EXPECT_EQ(0U, errors_.size()); + + ApplyPolicies(); + base::Value* value; + EXPECT_TRUE(prefs_.GetValue(prefs::kPolicyThemeColor, &value)); + ASSERT_TRUE(value); + EXPECT_EQ(value->GetInt(), static_cast<int>(expected_color)); + } + + void CheckInvalidPolicy(const base::Value& policy_value) { + EXPECT_FALSE(CheckPolicy(policy_value.Clone())); + EXPECT_NE(0U, errors_.size()); + } + + void CheckInvalidValuePolicy(std::string&& policy_value) { + base::Value theme_color_value(std::move(policy_value)); + CheckInvalidPolicy(theme_color_value); + } + + void CheckInvalidTypePolicy(const base::Value& policy_value) { + EXPECT_FALSE(CheckPolicy(policy_value.Clone())); + EXPECT_NE(0U, errors_.size()); + } + + ThemeColorPolicyHandler handler_; + PolicyErrorMap errors_; + PolicyMap policies_; + PrefValueMap prefs_; +}; + +TEST_F(ThemeColorPolicyHandlerTest, NoPolicy) { + EXPECT_TRUE(handler_.CheckPolicySettings(policies_, &errors_)); + EXPECT_EQ(0U, errors_.size()); +} + +TEST_F(ThemeColorPolicyHandlerTest, ValidValues) { + CheckValidPolicy("#000000", SkColorSetRGB(0, 0, 0)); + CheckValidPolicy("000000", SkColorSetRGB(0, 0, 0)); + CheckValidPolicy("#999999", SkColorSetRGB(153, 153, 153)); + CheckValidPolicy("#FFFFFF", SkColorSetRGB(255, 255, 255)); + CheckValidPolicy("#ffffff", SkColorSetRGB(255, 255, 255)); + CheckValidPolicy("#0a1B2c", SkColorSetRGB(10, 27, 44)); +} + +TEST_F(ThemeColorPolicyHandlerTest, InvalidValues) { + CheckInvalidValuePolicy("#00000"); + CheckInvalidValuePolicy("#000"); + CheckInvalidValuePolicy("#00000G"); + CheckInvalidValuePolicy("#zzzzzz"); + CheckInvalidValuePolicy("#00000!"); + CheckInvalidValuePolicy("#000 000"); + CheckInvalidValuePolicy("# 000000"); + CheckInvalidValuePolicy(" #000000"); + CheckInvalidValuePolicy("#000000 "); + CheckInvalidValuePolicy(" #000000 "); +} + +TEST_F(ThemeColorPolicyHandlerTest, InvalidTypes) { + base::Value value_int(123); + CheckInvalidPolicy(value_int); + base::Value value_float(1.0f); + CheckInvalidPolicy(value_float); +} + +} // namespace policy
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index 4fcbc9f..f491477 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -115,7 +115,7 @@ void OnExtensionLoaded(content::BrowserContext* browser_context, const extensions::Extension* extension) override { - if (!extension->is_theme()) + if (!extension->is_theme() || theme_service_->UsingPolicyTheme()) return; bool is_new_version = @@ -304,6 +304,12 @@ base::StringToInt(rgb[2], &b); BuildAutogeneratedThemeFromColor(SkColorSetRGB(r, g, b)); } + + pref_change_registrar_.Init(profile_->GetPrefs()); + pref_change_registrar_.Add( + prefs::kPolicyThemeColor, + base::BindRepeating(&ThemeService::HandlePolicyColorUpdate, + base::Unretained(this))); } void ThemeService::Shutdown() { @@ -352,6 +358,12 @@ } void ThemeService::UseDefaultTheme() { + if (UsingPolicyTheme()) { + DVLOG(1) + << "Default theme was not applied because a policy theme has been set."; + return; + } + if (ready_) base::RecordAction(base::UserMetricsAction("Themes_Reset")); @@ -389,17 +401,17 @@ } bool ThemeService::UsingAutogeneratedTheme() const { - bool autogenerated = ThemeHelper::IsAutogeneratedTheme(GetThemeSupplier()); - - DCHECK_EQ(autogenerated, - profile_->GetPrefs()->HasPrefPath(prefs::kAutogeneratedThemeColor)); - return autogenerated; + return ThemeHelper::IsAutogeneratedTheme(GetThemeSupplier()); } std::string ThemeService::GetThemeID() const { return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); } +bool ThemeService::UsingPolicyTheme() const { + return profile_->GetPrefs()->IsManagedPreference(prefs::kPolicyThemeColor); +} + void ThemeService::RemoveUnusedThemes() { // We do not want to garbage collect themes on startup (|ready_| is false). // Themes will get garbage collected after |kRemoveUnusedThemesStartupDelay|. @@ -457,6 +469,16 @@ } void ThemeService::BuildAutogeneratedThemeFromColor(SkColor color) { + if (UsingPolicyTheme()) { + DVLOG(1) << "Autogenerated theme was not applied because a policy theme" + " has been set."; + return; + } + BuildAutogeneratedThemeFromColor(color, /*store_user_prefs*/ true); +} + +void ThemeService::BuildAutogeneratedThemeFromColor(SkColor color, + bool store_in_prefs) { base::Optional<std::string> previous_theme_id; if (UsingExtensionTheme()) previous_theme_id = GetThemeID(); @@ -466,7 +488,8 @@ BrowserThemePack::BuildFromColor(color, pack.get()); SwapThemeSupplier(std::move(pack)); if (theme_supplier_) { - SetThemePrefsForColor(color); + if (store_in_prefs) + SetThemePrefsForColor(color); if (previous_theme_id.has_value()) DisableExtension(previous_theme_id.value()); NotifyThemeChanged(); @@ -477,6 +500,16 @@ return profile_->GetPrefs()->GetInteger(prefs::kAutogeneratedThemeColor); } +void ThemeService::BuildAutogeneratedPolicyTheme() { + BuildAutogeneratedThemeFromColor(GetPolicyThemeColor(), + /*store_user_prefs*/ false); +} + +SkColor ThemeService::GetPolicyThemeColor() const { + DCHECK(UsingPolicyTheme()); + return profile_->GetPrefs()->GetInteger(prefs::kPolicyThemeColor); +} + // static void ThemeService::DisableThemePackForTesting() { g_dont_write_theme_pack_for_testing = true; @@ -491,7 +524,8 @@ weak_ptr_factory_.GetWeakPtr(), GetThemeID()); } else if (UsingAutogeneratedTheme()) { reinstall_callback = base::BindOnce( - &ThemeService::BuildAutogeneratedThemeFromColor, + static_cast<void (ThemeService::*)(SkColor)>( + &ThemeService::BuildAutogeneratedThemeFromColor), weak_ptr_factory_.GetWeakPtr(), GetAutogeneratedThemeColor()); } else if (UsingSystemTheme()) { reinstall_callback = base::BindOnce(&ThemeService::UseSystemTheme, @@ -515,6 +549,12 @@ void ThemeService::SetCustomDefaultTheme( scoped_refptr<CustomThemeSupplier> theme_supplier) { + if (UsingPolicyTheme()) { + DVLOG(1) << "Custom default theme was not applied because a policy " + "theme has been set."; + return; + } + ClearAllThemeData(); SwapThemeSupplier(std::move(theme_supplier)); NotifyThemeChanged(); @@ -544,6 +584,13 @@ void ThemeService::InitFromPrefs() { FixInconsistentPreferencesIfNeeded(); + // If theme color policy was set while browser was off, apply it now. + if (UsingPolicyTheme()) { + BuildAutogeneratedPolicyTheme(); + set_ready(); + return; + } + std::string current_id = GetThemeID(); if (current_id == ThemeHelper::kDefaultThemeID) { if (ShouldInitWithSystemTheme()) @@ -596,6 +643,7 @@ void ThemeService::DoSetTheme(const extensions::Extension* extension, bool suppress_infobar) { DCHECK(extension->is_theme()); + DCHECK(!UsingPolicyTheme()); DCHECK(extensions::ExtensionSystem::Get(profile_) ->extension_service() ->IsExtensionEnabled(extension->id())); @@ -672,6 +720,12 @@ const extensions::ExtensionId& extension_id, scoped_refptr<BrowserThemePack> pack, bool suppress_infobar) { + if (UsingPolicyTheme()) { + DVLOG(1) << "Extension theme was not applied because a policy theme has " + "been set."; + return; + } + if (!pack->is_valid()) { // TODO(erg): We've failed to install the theme; perhaps we should tell the // user? http://crbug.com/34780 @@ -735,6 +789,15 @@ } } +void ThemeService::HandlePolicyColorUpdate() { + if (UsingPolicyTheme()) { + BuildAutogeneratedPolicyTheme(); + } else { + // If a policy theme is unset, load the previous theme from prefs. + InitFromPrefs(); + } +} + void ThemeService::ClearThemePrefs() { profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); profile_->GetPrefs()->ClearPref(prefs::kAutogeneratedThemeColor);
diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h index bf34208..592d40ae 100644 --- a/chrome/browser/themes/theme_service.h +++ b/chrome/browser/themes/theme_service.h
@@ -19,6 +19,7 @@ #include "chrome/browser/themes/theme_helper.h" #include "chrome/common/buildflags.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/prefs/pref_change_registrar.h" #include "extensions/buildflags/buildflags.h" #include "extensions/common/extension_id.h" #include "ui/base/theme_provider.h" @@ -122,6 +123,10 @@ // Virtual for testing. virtual bool UsingAutogeneratedTheme() const; + // Whether current theme colors are enforced through a policy. + // Virtual for testing. + virtual bool UsingPolicyTheme() const; + // Gets the id of the last installed theme. (The theme may have been further // locally customized.) virtual std::string GetThemeID() const; @@ -141,9 +146,19 @@ // Builds an autogenerated theme from a given |color| and applies it. virtual void BuildAutogeneratedThemeFromColor(SkColor color); + // Builds an autogenerated theme from a given |color| and applies it. + virtual void BuildAutogeneratedThemeFromColor(SkColor color, + bool store_in_prefs); + // Returns the theme color for an autogenerated theme. virtual SkColor GetAutogeneratedThemeColor() const; + // Builds an autogenerated theme from the applied policy color and applies it. + virtual void BuildAutogeneratedPolicyTheme(); + + // Returns the theme color for the current policy theme. + virtual SkColor GetPolicyThemeColor() const; + // Returns |ThemeService::ThemeReinstaller| for the current theme. std::unique_ptr<ThemeService::ThemeReinstaller> BuildReinstallerForCurrentTheme(); @@ -257,6 +272,10 @@ void SetSupervisedUserTheme(); #endif + // Handles theme color policy pref updates. if policy value contains valid + // color(s), sets browser theme accordingly. + void HandlePolicyColorUpdate(); + // Functions that modify theme prefs. void ClearThemePrefs(); void SetThemePrefsForExtension(const extensions::Extension* extension); @@ -265,6 +284,7 @@ bool DisableExtension(const std::string& extension_id); Profile* profile_; + PrefChangeRegistrar pref_change_registrar_; const ThemeHelper& theme_helper_; scoped_refptr<CustomThemeSupplier> theme_supplier_;
diff --git a/chrome/browser/themes/theme_service_factory.cc b/chrome/browser/themes/theme_service_factory.cc index 4f82e3d..dc2350f0b 100644 --- a/chrome/browser/themes/theme_service_factory.cc +++ b/chrome/browser/themes/theme_service_factory.cc
@@ -111,6 +111,7 @@ registry->RegisterStringPref(prefs::kCurrentThemeID, ThemeHelper::kDefaultThemeID); registry->RegisterIntegerPref(prefs::kAutogeneratedThemeColor, 0); + registry->RegisterIntegerPref(prefs::kPolicyThemeColor, SK_ColorTRANSPARENT); } content::BrowserContext* ThemeServiceFactory::GetBrowserContextToUse(
diff --git a/chrome/browser/themes/theme_service_unittest.cc b/chrome/browser/themes/theme_service_unittest.cc index fdba08b..a6e49eb 100644 --- a/chrome/browser/themes/theme_service_unittest.cc +++ b/chrome/browser/themes/theme_service_unittest.cc
@@ -27,6 +27,7 @@ #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_util.h" @@ -95,6 +96,7 @@ extensions::ExtensionServiceTestBase::SetUp(); extensions::ExtensionServiceTestBase::ExtensionServiceInitParams params = CreateDefaultInitParams(); + params.pref_file = base::FilePath(); InitializeExtensionService(params); service_->Init(); registry_ = extensions::ExtensionRegistry::Get(profile()); @@ -684,4 +686,81 @@ EXPECT_EQ(theme_service_->GetThemeSupplier(), nullptr); } +// Sets and unsets themes using the BrowserThemeColor policy. +TEST_F(ThemeServiceTest, PolicyThemeColorSet) { + theme_service_->UseDefaultTheme(); + EXPECT_TRUE(theme_service_->UsingDefaultTheme()); + EXPECT_FALSE(theme_service_->UsingAutogeneratedTheme()); + EXPECT_FALSE(theme_service_->UsingPolicyTheme()); + + // Setting a blank policy color shouldn't cause any theme updates. + profile_->GetPrefs()->ClearPref(prefs::kPolicyThemeColor); + EXPECT_TRUE(theme_service_->UsingDefaultTheme()); + EXPECT_FALSE(theme_service_->UsingAutogeneratedTheme()); + EXPECT_FALSE(theme_service_->UsingPolicyTheme()); + + // Setting a valid policy color causes theme to update. The applied theme is + // autogenerated based on the policy color. + profile_->GetTestingPrefService()->SetManagedPref( + prefs::kPolicyThemeColor, std::make_unique<base::Value>(100)); + EXPECT_FALSE(theme_service_->UsingDefaultTheme()); + EXPECT_TRUE(theme_service_->UsingAutogeneratedTheme()); + EXPECT_TRUE(theme_service_->UsingPolicyTheme()); + // Policy theme is not saved in prefs. + EXPECT_EQ(theme_service_->GetThemeID(), std::string()); + + // Unsetting policy theme and setting autogenerated theme. + profile_->GetTestingPrefService()->RemoveManagedPref( + prefs::kPolicyThemeColor); + theme_service_->BuildAutogeneratedThemeFromColor( + SkColorSetRGB(100, 100, 100)); + EXPECT_FALSE(theme_service_->UsingDefaultTheme()); + EXPECT_TRUE(theme_service_->UsingAutogeneratedTheme()); + EXPECT_FALSE(theme_service_->UsingPolicyTheme()); + EXPECT_EQ(ThemeService::kAutogeneratedThemeID, theme_service_->GetThemeID()); + + // Setting a different policy color. + profile_->GetTestingPrefService()->SetManagedPref( + prefs::kPolicyThemeColor, std::make_unique<base::Value>(-100)); + EXPECT_FALSE(theme_service_->UsingDefaultTheme()); + EXPECT_TRUE(theme_service_->UsingAutogeneratedTheme()); + EXPECT_TRUE(theme_service_->UsingPolicyTheme()); + EXPECT_EQ(ThemeService::kAutogeneratedThemeID, theme_service_->GetThemeID()); + + // Removing policy color reverts the theme to the one saved in prefs, or + // the default theme if prefs are empty. + profile_->GetTestingPrefService()->RemoveManagedPref( + prefs::kPolicyThemeColor); + EXPECT_FALSE(theme_service_->UsingDefaultTheme()); + EXPECT_TRUE(theme_service_->UsingAutogeneratedTheme()); + EXPECT_FALSE(theme_service_->UsingPolicyTheme()); + EXPECT_EQ(ThemeService::kAutogeneratedThemeID, theme_service_->GetThemeID()); + + // Install extension theme. + ThemeScoper scoper = LoadUnpackedTheme(); + EXPECT_TRUE(theme_service_->UsingExtensionTheme()); + EXPECT_FALSE(theme_service_->UsingPolicyTheme()); + EXPECT_EQ(scoper.extension_id(), theme_service_->GetThemeID()); + + // Applying policy theme should disable the extension theme. + profile_->GetTestingPrefService()->SetManagedPref( + prefs::kPolicyThemeColor, std::make_unique<base::Value>(100)); + EXPECT_FALSE(theme_service_->UsingExtensionTheme()); + EXPECT_TRUE(theme_service_->UsingPolicyTheme()); + + // Cannot set other themes while a policy theme is applied. + theme_service_->BuildAutogeneratedThemeFromColor( + SkColorSetRGB(100, 100, 100)); + theme_service_->UseDefaultTheme(); + EXPECT_FALSE(theme_service_->UsingDefaultTheme()); + EXPECT_TRUE(theme_service_->UsingAutogeneratedTheme()); + EXPECT_FALSE(theme_service_->UsingExtensionTheme()); + EXPECT_TRUE(theme_service_->UsingPolicyTheme()); + + // Removing policy color unsets the policy theme. + profile_->GetTestingPrefService()->RemoveManagedPref( + prefs::kPolicyThemeColor); + EXPECT_FALSE(theme_service_->UsingPolicyTheme()); +} + } // namespace theme_service_internal
diff --git a/chrome/browser/themes/theme_syncable_service.cc b/chrome/browser/themes/theme_syncable_service.cc index 21cd36128..e936747 100644 --- a/chrome/browser/themes/theme_syncable_service.cc +++ b/chrome/browser/themes/theme_syncable_service.cc
@@ -312,6 +312,10 @@ return false; } + // If theme was set through policy, it should be unsyncable. + if (theme_service_->UsingPolicyTheme()) + return false; + theme_specifics->Clear(); theme_specifics->set_use_custom_theme(false);
diff --git a/chrome/browser/themes/theme_syncable_service_unittest.cc b/chrome/browser/themes/theme_syncable_service_unittest.cc index f2ecccf..548e148 100644 --- a/chrome/browser/themes/theme_syncable_service_unittest.cc +++ b/chrome/browser/themes/theme_syncable_service_unittest.cc
@@ -78,6 +78,7 @@ theme_extension_ = extension; using_system_theme_ = false; using_default_theme_ = false; + using_policy_theme_ = false; might_show_infobar_ = !suppress_infobar; color_ = 0; } @@ -88,12 +89,14 @@ theme_extension_.reset(); using_system_theme_ = false; using_default_theme_ = false; + using_policy_theme_ = false; } void UseDefaultTheme() override { is_dirty_ = true; using_default_theme_ = true; using_system_theme_ = false; + using_policy_theme_ = false; theme_extension_.reset(); color_ = 0; } @@ -102,10 +105,20 @@ is_dirty_ = true; using_system_theme_ = true; using_default_theme_ = false; + using_policy_theme_ = false; theme_extension_.reset(); color_ = 0; } + void BuildAutogeneratedPolicyTheme() override { + is_dirty_ = true; + color_ = SkColorSetRGB(100, 100, 0); + theme_extension_.reset(); + using_system_theme_ = false; + using_default_theme_ = false; + using_policy_theme_ = true; + } + bool IsSystemThemeDistinctFromDefaultTheme() const override { return distinct_from_default_theme_; } @@ -122,6 +135,8 @@ bool UsingAutogeneratedTheme() const override { return color_ != 0; } + bool UsingPolicyTheme() const override { return using_policy_theme_; } + string GetThemeID() const override { return UsingExtensionTheme() ? theme_extension_->id() : std::string(); } @@ -141,6 +156,7 @@ private: bool using_system_theme_ = false; bool using_default_theme_ = false; + bool using_policy_theme_ = false; bool distinct_from_default_theme_ = false; scoped_refptr<const extensions::Extension> theme_extension_; bool is_dirty_ = false; @@ -551,6 +567,24 @@ theme_specifics.autogenerated_theme().color()); } +TEST_F(ThemeSyncableServiceTest, UpdateThemeSpecifics_CurrentTheme_Policy) { + // Set up theme service to use policy theme. + fake_theme_service_->BuildAutogeneratedPolicyTheme(); + + base::Optional<syncer::ModelError> error = + theme_sync_service_->MergeDataAndStartSyncing( + syncer::THEMES, syncer::SyncDataList(), + std::unique_ptr<syncer::SyncChangeProcessor>( + new syncer::SyncChangeProcessorWrapperForTest( + fake_change_processor_.get())), + std::unique_ptr<syncer::SyncErrorFactory>( + new syncer::SyncErrorFactoryMock())); + EXPECT_FALSE(error.has_value()) << error.value().message(); + // Applying policy theme doesn't trigger sync changes. + const syncer::SyncChangeList& changes = fake_change_processor_->changes(); + ASSERT_EQ(0u, changes.size()); +} + TEST_F(ThemeSyncableServiceTest, GetAllSyncDataForTesting_Extension) { // Set up theme service to use custom theme. fake_theme_service_->SetTheme(theme_extension_.get()); @@ -585,6 +619,16 @@ theme_specifics.autogenerated_theme().color()); } +TEST_F(ThemeSyncableServiceTest, GetAllSyncDataForTesting_Policy) { + // Set up theme service to use policy theme. + fake_theme_service_->BuildAutogeneratedPolicyTheme(); + + // Themes applied through policy shouldn't be synced. + syncer::SyncDataList data_list = + theme_sync_service_->GetAllSyncDataForTesting(syncer::THEMES); + ASSERT_EQ(0u, data_list.size()); +} + TEST_F(ThemeSyncableServiceTest, ProcessSyncThemeChange_Extension) { // Set up theme service to use default theme. fake_theme_service_->UseDefaultTheme();
diff --git a/chrome/browser/translate/translate_manager_render_view_host_unittest.cc b/chrome/browser/translate/translate_manager_render_view_host_unittest.cc index 6ecc439..469781a 100644 --- a/chrome/browser/translate/translate_manager_render_view_host_unittest.cc +++ b/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
@@ -1282,12 +1282,10 @@ PrefService* prefs = profile->GetPrefs(); PrefChangeRegistrar registrar; registrar.Init(prefs); - registrar.Add(translate::TranslatePrefs::kPrefAlwaysTranslateLists, - pref_callback_); + registrar.Add(prefs::kPrefAlwaysTranslateList, pref_callback_); std::unique_ptr<translate::TranslatePrefs> translate_prefs( ChromeTranslateClient::CreateTranslatePrefs(prefs)); - SetPrefObserverExpectation( - translate::TranslatePrefs::kPrefAlwaysTranslateLists); + SetPrefObserverExpectation(prefs::kPrefAlwaysTranslateList); translate_prefs->AddLanguagePairToAlwaysTranslateList("fr", "en"); // Load a page in French. @@ -1324,8 +1322,7 @@ // Now revert the always translate pref and make sure we go back to expected // behavior, which is show a "before translate" infobar. - SetPrefObserverExpectation( - translate::TranslatePrefs::kPrefAlwaysTranslateLists); + SetPrefObserverExpectation(prefs::kPrefAlwaysTranslateList); translate_prefs->RemoveLanguagePairFromAlwaysTranslateList("fr", "en"); SimulateNavigation(GURL("http://www.google.fr"), "fr", true); EXPECT_FALSE(GetTranslateMessage(&source_lang, &target_lang));
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 1492397..ef01360 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3149,8 +3149,6 @@ "cocoa/renderer_context_menu/render_view_context_menu_mac.mm", "cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.h", "cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm", - "cocoa/rosetta_required_infobar_delegate.h", - "cocoa/rosetta_required_infobar_delegate.mm", "cocoa/scoped_menu_bar_lock.h", "cocoa/scoped_menu_bar_lock.mm", "cocoa/screentime/fake_webpage_controller.h", @@ -3228,7 +3226,6 @@ "//extensions/components/native_app_window", "//third_party/google_toolbox_for_mac", "//third_party/mozilla", - "//third_party/widevine/cdm:buildflags", "//ui/accelerated_widget_mac:accelerated_widget_mac", ] include_dirs = [ "$target_gen_dir" ]
diff --git a/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc b/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc index 4ef8406..58b0b5ae 100644 --- a/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc +++ b/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc
@@ -48,9 +48,9 @@ #define EXPECT_VISIBLE_NOTIFICATIONS_BY_PREFIXED_ID(prefix_) \ { \ - if (!FindVisibleNotificationsByPrefixedId(prefix_).empty()) \ + if (!FindVisibleNotificationsByPrefixedId(prefix_).empty()) { \ return; \ - \ + } \ MockMessageCenterObserver mock; \ ScopedObserver<MessageCenter, MessageCenterObserver> observer_{&mock}; \ observer_.Add(MessageCenter::Get()); \ @@ -188,9 +188,7 @@ class AssistantTimersBrowserTest : public MixinBasedInProcessBrowserTest { public: - AssistantTimersBrowserTest() { - feature_list_.InitAndEnableFeature(features::kAssistantTimersV2); - } + AssistantTimersBrowserTest() = default; AssistantTimersBrowserTest(const AssistantTimersBrowserTest&) = delete; AssistantTimersBrowserTest& operator=(const AssistantTimersBrowserTest&) = @@ -206,7 +204,6 @@ AssistantTestMixin* tester() { return &tester_; } private: - base::test::ScopedFeatureList feature_list_; base::test::ScopedRestoreICUDefaultLocale locale_{"en_US"}; AssistantTestMixin tester_{&mixin_host_, this, embedded_test_server(), kMode, kVersion};
diff --git a/chrome/browser/ui/cocoa/rosetta_required_infobar_delegate.h b/chrome/browser/ui/cocoa/rosetta_required_infobar_delegate.h deleted file mode 100644 index 21debb3..0000000 --- a/chrome/browser/ui/cocoa/rosetta_required_infobar_delegate.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2020 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_COCOA_ROSETTA_REQUIRED_INFOBAR_DELEGATE_H_ -#define CHROME_BROWSER_UI_COCOA_ROSETTA_REQUIRED_INFOBAR_DELEGATE_H_ - -#include <string> - -#include "components/infobars/core/confirm_infobar_delegate.h" -#include "url/gurl.h" - -namespace content { -class WebContents; -} - -// This infobar displays a message that Rosetta is required to play protected -// media, and initiates an installation of Rosetta if the user wants. -class RosettaRequiredInfoBarDelegate : public ConfirmInfoBarDelegate { - public: - RosettaRequiredInfoBarDelegate(); - ~RosettaRequiredInfoBarDelegate() override; - RosettaRequiredInfoBarDelegate(const RosettaRequiredInfoBarDelegate& other) = - delete; - RosettaRequiredInfoBarDelegate& operator=( - const RosettaRequiredInfoBarDelegate& other) = delete; - - // Returns whether this infobar should show or not. - static bool ShouldShow(); - - // Creates an instance of this infobar and adds it to the provided - // WebContents. It is an error to call this method if !ShouldShow() outside - // tests - the correct strings are not guaranteed to be produced. - static void Create(content::WebContents* web_contents); - - private: - // ConfirmInfoBarDelegate: - infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; - std::u16string GetLinkText() const override; - GURL GetLinkURL() const override; - std::u16string GetMessageText() const override; - int GetButtons() const override; - std::u16string GetButtonLabel(InfoBarButton button) const override; - bool Accept() override; -}; - -#endif // CHROME_BROWSER_UI_COCOA_ROSETTA_REQUIRED_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/ui/cocoa/rosetta_required_infobar_delegate.mm b/chrome/browser/ui/cocoa/rosetta_required_infobar_delegate.mm deleted file mode 100644 index 43630f40..0000000 --- a/chrome/browser/ui/cocoa/rosetta_required_infobar_delegate.mm +++ /dev/null
@@ -1,105 +0,0 @@ -// Copyright 2020 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/cocoa/rosetta_required_infobar_delegate.h" - -#import <AppKit/AppKit.h> - -#include <memory> - -#include "base/bind.h" -#include "base/mac/rosetta.h" -#include "base/mac/scoped_nsobject.h" -#include "base/threading/thread_task_runner_handle.h" -#include "build/build_config.h" -#include "chrome/browser/component_updater/widevine_cdm_component_installer.h" -#include "chrome/browser/infobars/infobar_service.h" -#include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/infobars/core/infobar.h" -#include "components/strings/grit/components_strings.h" -#include "third_party/widevine/cdm/buildflags.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/l10n/l10n_util_mac.h" - -// static -bool RosettaRequiredInfoBarDelegate::ShouldShow() { -#if defined(ARCH_CPU_ARM64) && BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) - return component_updater::WasWidevineCdmComponentRejectedDueToNoRosetta(); -#else - return false; -#endif // ARCH_CPU_ARM64 -} - -// static -void RosettaRequiredInfoBarDelegate::Create( - content::WebContents* web_contents) { - auto* infobar_service = InfoBarService::FromWebContents(web_contents); - - if (infobar_service) { - infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar( - std::make_unique<RosettaRequiredInfoBarDelegate>())); - } -} - -RosettaRequiredInfoBarDelegate::RosettaRequiredInfoBarDelegate() = default; -RosettaRequiredInfoBarDelegate::~RosettaRequiredInfoBarDelegate() = default; - -infobars::InfoBarDelegate::InfoBarIdentifier -RosettaRequiredInfoBarDelegate::GetIdentifier() const { - return ROSETTA_REQUIRED_INFOBAR_DELEGATE; -} - -std::u16string RosettaRequiredInfoBarDelegate::GetLinkText() const { - return l10n_util::GetStringUTF16(IDS_ROSETTA_REQUIRED_INFOBAR_LINK_TEXT); -} - -GURL RosettaRequiredInfoBarDelegate::GetLinkURL() const { - return GURL("https://support.google.com/chrome/?p=mac_ARM"); -} - -std::u16string RosettaRequiredInfoBarDelegate::GetMessageText() const { - return l10n_util::GetStringUTF16(IDS_ROSETTA_REQUIRED_INFOBAR_TEXT); -} - -int RosettaRequiredInfoBarDelegate::GetButtons() const { - return BUTTON_OK; -} - -std::u16string RosettaRequiredInfoBarDelegate::GetButtonLabel( - InfoBarButton button) const { - return l10n_util::GetStringUTF16(IDS_ROSETTA_REQUIRED_INFOBAR_BUTTON_TEXT); -} - -bool RosettaRequiredInfoBarDelegate::Accept() { -#if defined(ARCH_CPU_ARM64) - base::mac::RequestRosettaInstallation( - l10n_util::GetStringUTF16(IDS_ROSETTA_INSTALL_TITLE), - l10n_util::GetStringUTF16(IDS_ROSETTA_INSTALL_BODY), - base::BindOnce([](base::mac::RosettaInstallationResult result) { - if (result != - base::mac::RosettaInstallationResult::kInstallationSuccess && - result != base::mac::RosettaInstallationResult::kAlreadyInstalled) { - return; - } - - base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]); - [alert setMessageText:l10n_util::GetNSString( - IDS_ROSETTA_INSTALL_RESTART_DIALOG)]; - [alert addButtonWithTitle:l10n_util::GetNSString( - IDS_ROSETTA_INSTALL_RESTART_DIALOG_NOW)]; - [alert - addButtonWithTitle:l10n_util::GetNSString( - IDS_ROSETTA_INSTALL_RESTART_DIALOG_LATER)]; - NSModalResponse response = [alert runModal]; - - if (response == NSAlertFirstButtonReturn) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&chrome::AttemptRestart)); - } - })); -#endif // ARCH_CPU_ARM64 - return true; -}
diff --git a/chrome/browser/ui/cocoa/screentime/tab_helper.mm b/chrome/browser/ui/cocoa/screentime/tab_helper.mm index 9dadbf6e..42586d5 100644 --- a/chrome/browser/ui/cocoa/screentime/tab_helper.mm +++ b/chrome/browser/ui/cocoa/screentime/tab_helper.mm
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/cocoa/screentime/tab_helper.h" #include "chrome/browser/ui/cocoa/screentime/webpage_controller.h" #include "chrome/browser/ui/cocoa/screentime/webpage_controller_impl.h" +#include "content/public/browser/media_session.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" @@ -72,10 +73,13 @@ } void TabHelper::OnBlockedChanged(bool blocked) { - // TODO: Pause/resume playing media, update occlusion state on the - // WebContents, and so on. Getting this behavior right will probably require - // some care. - NOTIMPLEMENTED(); + // TODO: Update occlusion state on the WebContents, and so on. + // Getting this behavior right will probably require some care. + auto* media_session = content::MediaSession::Get(web_contents()); + if (blocked) + media_session->Suspend(content::MediaSession::SuspendType::kSystem); + else + media_session->Resume(content::MediaSession::SuspendType::kSystem); } WEB_CONTENTS_USER_DATA_KEY_IMPL(TabHelper)
diff --git a/chrome/browser/ui/cocoa/screentime/webpage_controller_impl.h b/chrome/browser/ui/cocoa/screentime/webpage_controller_impl.h index 8f02dac..b78ad5a9 100644 --- a/chrome/browser/ui/cocoa/screentime/webpage_controller_impl.h +++ b/chrome/browser/ui/cocoa/screentime/webpage_controller_impl.h
@@ -8,6 +8,7 @@ #include "base/mac/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/screentime/webpage_controller.h" +@class BlockedObserver; @class STWebpageController; namespace screentime { @@ -26,6 +27,7 @@ private: base::scoped_nsobject<STWebpageController> platform_controller_; + base::scoped_nsobject<BlockedObserver> blocked_observer_; BlockedChangedCallback blocked_changed_callback_; };
diff --git a/chrome/browser/ui/cocoa/screentime/webpage_controller_impl.mm b/chrome/browser/ui/cocoa/screentime/webpage_controller_impl.mm index 647e174..1ae7527 100644 --- a/chrome/browser/ui/cocoa/screentime/webpage_controller_impl.mm +++ b/chrome/browser/ui/cocoa/screentime/webpage_controller_impl.mm
@@ -53,6 +53,9 @@ WebpageControllerImpl::WebpageControllerImpl( const BlockedChangedCallback& blocked_changed_callback) : platform_controller_([[STWebpageController alloc] init]), + blocked_observer_([[BlockedObserver alloc] + initWithController:this + nativeController:platform_controller_.get()]), blocked_changed_callback_(blocked_changed_callback) { NSError* error = nil; NSString* bundle_id = base::SysUTF8ToNSString(base::mac::BaseBundleID());
diff --git a/chrome/browser/ui/views/accessibility/caption_bubble.cc b/chrome/browser/ui/views/accessibility/caption_bubble.cc index d0d656f..4b391a0b 100644 --- a/chrome/browser/ui/views/accessibility/caption_bubble.cc +++ b/chrome/browser/ui/views/accessibility/caption_bubble.cc
@@ -92,6 +92,56 @@ base::UmaHistogramEnumeration("Accessibility.LiveCaption.Session", event); } +std::unique_ptr<views::ImageButton> BuildImageButton( + views::Button::PressedCallback callback, + const int tooltip_text_id) { + auto button = views::CreateVectorImageButton(std::move(callback)); + button->SetTooltipText(l10n_util::GetStringUTF16(tooltip_text_id)); + button->SizeToPreferredSize(); + views::InstallCircleHighlightPathGenerator( + button.get(), gfx::Insets(kButtonCircleHighlightPaddingDip)); + return button; +} + +// ui::CaptionStyle styles are CSS strings that can sometimes have !important. +// This method removes " !important" if it exists at the end of a CSS string. +std::string MaybeRemoveCSSImportant(std::string css_string) { + RE2::Replace(&css_string, "\\s+!important", ""); + return css_string; +} + +// Parses a CSS color string that is in the form rgba and has a non-zero alpha +// value into an SkColor and sets it to be the value of the passed-in SkColor +// address. Returns whether or not the operation was a success. +// +// `css_string` is the CSS color string passed in. It is in the form +// rgba(#,#,#,#). r, g, and b are integers between 0 and 255, inclusive. +// a is a double between 0.0 and 1.0. There may be whitespace in between the +// commas. +// `sk_color` is the address of an SKColor. If the operation is a success, the +// function will set sk_color's value to be the parsed SkColor. If the +// operation is not a success, sk_color's value will not change. +// +// As of spring 2021, all OS's use rgba to define the caption style colors. +// However, the ui::CaptionStyle spec also allows for the use of any valid CSS +// color spec. This function will need to be revisited should ui::CaptionStyle +// colors use non-rgba to define their colors. +bool ParseNonTransparentRGBACSSColorString(std::string css_string, + SkColor* sk_color) { + std::string rgba = MaybeRemoveCSSImportant(css_string); + if (rgba.empty()) + return false; + uint16_t r, g, b; + double a; + bool match = RE2::FullMatch( + rgba, "rgba\\((\\d+),\\s*(\\d+),\\s*(\\d+),\\s*(\\d+\\.?\\d*)\\)", &r, &g, + &b, &a); + match &= a != 0; + if (match) + *sk_color = SkColorSetARGB(a * 255, r, g, b); + return match; +} + } // namespace namespace captions { @@ -414,11 +464,6 @@ ->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kEnd); UseCompactMargins(); - // TODO(crbug.com/1055150): Use system caption color scheme rather than - // hard-coding the colors. - SkColor caption_bubble_color_ = - SkColorSetA(gfx::kGoogleGrey900, kCaptionBubbleAlpha); - set_color(caption_bubble_color_); set_close_on_deactivate(false); // The caption bubble starts out hidden and unable to be activated. SetCanActivate(false); @@ -426,7 +471,6 @@ auto label = std::make_unique<CaptionBubbleLabel>(); label->SetMultiLine(true); label->SetMaximumWidth(kMaxWidthDip - kSidePaddingDip * 2); - label->SetEnabledColor(SK_ColorWHITE); label->SetBackgroundColor(SK_ColorTRANSPARENT); label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); label->SetVerticalAlignment(gfx::VerticalAlignment::ALIGN_TOP); @@ -440,21 +484,17 @@ label->SetTruncateLength(0); auto title = std::make_unique<views::Label>(); - title->SetEnabledColor(gfx::kGoogleGrey500); title->SetBackgroundColor(SK_ColorTRANSPARENT); title->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); title->SetText(l10n_util::GetStringUTF16(IDS_LIVE_CAPTION_BUBBLE_TITLE)); title->GetViewAccessibility().OverrideIsIgnored(true); auto error_text = std::make_unique<views::Label>(); - error_text->SetEnabledColor(SK_ColorWHITE); error_text->SetBackgroundColor(SK_ColorTRANSPARENT); error_text->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); error_text->SetText(l10n_util::GetStringUTF16(IDS_LIVE_CAPTION_BUBBLE_ERROR)); auto error_icon = std::make_unique<views::ImageView>(); - error_icon->SetImage( - gfx::CreateVectorIcon(vector_icons::kErrorOutlineIcon, SK_ColorWHITE)); auto error_message = std::make_unique<views::View>(); error_message @@ -467,20 +507,18 @@ views::Button::PressedCallback expand_or_collapse_callback = base::BindRepeating(&CaptionBubble::ExpandOrCollapseButtonPressed, base::Unretained(this)); - auto expand_button = - BuildImageButton(expand_or_collapse_callback, kCaretDownIcon, - IDS_LIVE_CAPTION_BUBBLE_EXPAND); + auto expand_button = BuildImageButton(expand_or_collapse_callback, + IDS_LIVE_CAPTION_BUBBLE_EXPAND); expand_button->SetVisible(!is_expanded_); - auto collapse_button = - BuildImageButton(std::move(expand_or_collapse_callback), kCaretUpIcon, - IDS_LIVE_CAPTION_BUBBLE_COLLAPSE); + auto collapse_button = BuildImageButton( + std::move(expand_or_collapse_callback), IDS_LIVE_CAPTION_BUBBLE_COLLAPSE); collapse_button->SetVisible(is_expanded_); - auto close_button = BuildImageButton( - base::BindRepeating(&CaptionBubble::CloseButtonPressed, - base::Unretained(this)), - vector_icons::kCloseRoundedIcon, IDS_LIVE_CAPTION_BUBBLE_CLOSE); + auto close_button = + BuildImageButton(base::BindRepeating(&CaptionBubble::CloseButtonPressed, + base::Unretained(this)), + IDS_LIVE_CAPTION_BUBBLE_CLOSE); title_ = content_container->AddChildView(std::move(title)); label_ = content_container->AddChildView(std::move(label)); @@ -496,24 +534,10 @@ close_button_ = AddChildView(std::move(close_button)); content_container_ = AddChildView(std::move(content_container)); - UpdateTextSize(); + SetCaptionBubbleStyle(); UpdateContentSize(); } -std::unique_ptr<views::ImageButton> CaptionBubble::BuildImageButton( - views::Button::PressedCallback callback, - const gfx::VectorIcon& icon, - const int tooltip_text_id) { - auto button = views::CreateVectorImageButton(std::move(callback)); - views::SetImageFromVectorIcon(button.get(), icon, kButtonDip, SK_ColorWHITE); - button->SetTooltipText(l10n_util::GetStringUTF16(tooltip_text_id)); - button->SetInkDropBaseColor(SkColor(gfx::kGoogleGrey600)); - button->SizeToPreferredSize(); - views::InstallCircleHighlightPathGenerator( - button.get(), gfx::Insets(kButtonCircleHighlightPaddingDip)); - return button; -} - bool CaptionBubble::ShouldShowCloseButton() const { // We draw our own close button so that we can capture the button presses and // so we can customize its appearance. @@ -726,7 +750,7 @@ void CaptionBubble::UpdateCaptionStyle( base::Optional<ui::CaptionStyle> caption_style) { caption_style_ = caption_style; - UpdateTextSize(); + SetCaptionBubbleStyle(); Redraw(); } @@ -742,27 +766,45 @@ return is_expanded_ ? kNumLinesExpanded : kNumLinesCollapsed; } +void CaptionBubble::SetCaptionBubbleStyle() { + SetTextSizeAndFontFamily(); + SetTextColor(); + SetBackgroundColor(); +} + double CaptionBubble::GetTextScaleFactor() { double textScaleFactor = 1; if (caption_style_) { - // ui::CaptionStyle states that text_size is percentage as a CSS string. It - // can sometimes have !important which is why this is a partial match. - bool match = RE2::PartialMatch(caption_style_->text_size, "(\\d+)%", - &textScaleFactor); - textScaleFactor = match ? textScaleFactor / 100 : 1; + std::string text_size = MaybeRemoveCSSImportant(caption_style_->text_size); + if (!text_size.empty()) { + // ui::CaptionStyle states that text_size is percentage as a CSS string. + bool match = + RE2::FullMatch(text_size, "(\\d+\\.?\\d*)%", &textScaleFactor); + textScaleFactor = match ? textScaleFactor / 100 : 1; + } } return textScaleFactor; } -void CaptionBubble::UpdateTextSize() { +void CaptionBubble::SetTextSizeAndFontFamily() { double textScaleFactor = GetTextScaleFactor(); + std::vector<std::string> font_names; + if (caption_style_) { + std::string font_family = + MaybeRemoveCSSImportant(caption_style_->font_family); + if (!font_family.empty()) + font_names.push_back(font_family); + } + font_names.push_back(kPrimaryFont); + font_names.push_back(kSecondaryFont); + font_names.push_back(kTertiaryFont); + const gfx::FontList font_list = - gfx::FontList({kPrimaryFont, kSecondaryFont, kTertiaryFont}, - gfx::Font::FontStyle::NORMAL, kFontSizePx * textScaleFactor, - gfx::Font::Weight::NORMAL); + gfx::FontList(font_names, gfx::Font::FontStyle::NORMAL, + kFontSizePx * textScaleFactor, gfx::Font::Weight::NORMAL); label_->SetFontList(font_list); - title_->SetFontList(font_list); + title_->SetFontList(font_list.DeriveWithStyle(gfx::Font::FontStyle::ITALIC)); error_text_->SetFontList(font_list); label_->SetLineHeight(kLineHeightDip * textScaleFactor); @@ -772,6 +814,42 @@ kErrorImageSizeDip * textScaleFactor)); } +void CaptionBubble::SetTextColor() { + SkColor text_color = SK_ColorWHITE; // The default text color is white. + if (caption_style_) + ParseNonTransparentRGBACSSColorString(caption_style_->text_color, + &text_color); + label_->SetEnabledColor(text_color); + title_->SetEnabledColor(text_color); + error_text_->SetEnabledColor(text_color); + + error_icon_->SetImage( + gfx::CreateVectorIcon(vector_icons::kErrorOutlineIcon, text_color)); + views::SetImageFromVectorIcon(close_button_, vector_icons::kCloseRoundedIcon, + kButtonDip, text_color); + views::SetImageFromVectorIcon(expand_button_, kCaretDownIcon, kButtonDip, + text_color); + views::SetImageFromVectorIcon(collapse_button_, kCaretUpIcon, kButtonDip, + text_color); + + close_button_->SetInkDropBaseColor(text_color); + expand_button_->SetInkDropBaseColor(text_color); + collapse_button_->SetInkDropBaseColor(text_color); +} + +void CaptionBubble::SetBackgroundColor() { + // The default background color is Google Grey 900 with 90% opacity. + SkColor background_color = + SkColorSetA(gfx::kGoogleGrey900, kCaptionBubbleAlpha); + if (caption_style_ && !ParseNonTransparentRGBACSSColorString( + caption_style_->window_color, &background_color)) { + ParseNonTransparentRGBACSSColorString(caption_style_->background_color, + &background_color); + } + set_color(background_color); + OnThemeChanged(); // Need to call `OnThemeChanged` after calling `set_color`. +} + void CaptionBubble::UpdateContentSize() { double text_scale_factor = GetTextScaleFactor(); int content_height =
diff --git a/chrome/browser/ui/views/accessibility/caption_bubble.h b/chrome/browser/ui/views/accessibility/caption_bubble.h index 93a6e21..f5a8619c 100644 --- a/chrome/browser/ui/views/accessibility/caption_bubble.h +++ b/chrome/browser/ui/views/accessibility/caption_bubble.h
@@ -21,10 +21,6 @@ class RetainingOneShotTimer; } -namespace gfx { -struct VectorIcon; -} - namespace views { class Label; class ImageButton; @@ -64,8 +60,7 @@ // created when a tab activates and exists for the lifetime of that tab. void SetModel(CaptionBubbleModel* model); - // Changes the caption style of the caption bubble. For now, this only sets - // the caption text size. + // Changes the caption style of the caption bubble. void UpdateCaptionStyle(base::Optional<ui::CaptionStyle> caption_style); // Returns whether the bubble has activity, with the above definition of @@ -130,24 +125,26 @@ // Returns the number of lines in the caption bubble label that are rendered. size_t GetNumLinesInLabel() const; - - double GetTextScaleFactor(); int GetNumLinesVisible(); - void UpdateTextSize(); void UpdateContentSize(); void Redraw(); void Hide(); - std::unique_ptr<views::ImageButton> BuildImageButton( - views::Button::PressedCallback callback, - const gfx::VectorIcon& icon, - const int tooltip_text_id); - std::vector<std::string> GetAXLineTextForTesting(); + + // The following methods set the caption bubble style based on the user's + // preferences, which are stored in `caption_style_`. + void SetCaptionBubbleStyle(); + double GetTextScaleFactor(); + void SetTextSizeAndFontFamily(); + void SetTextColor(); + void SetBackgroundColor(); // After 5 seconds of inactivity, hide the caption bubble. Activity is defined // as transcription received from the speech service or user interacting with // the bubble through focus, pressing buttons, or dragging. void OnInactivityTimeout(); + std::vector<std::string> GetAXLineTextForTesting(); + // Unowned. Owned by views hierarchy. CaptionBubbleLabel* label_; views::Label* title_;
diff --git a/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc b/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc index ee1b15d..b874194 100644 --- a/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc +++ b/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc
@@ -587,72 +587,253 @@ } IN_PROC_BROWSER_TEST_F(CaptionBubbleControllerViewsTest, - UpdateCaptionTextSize) { - int textSize = 16; - int lineHeight = 24; - int bubbleHeight = 48; - int errorIconHeight = 20; + UpdateCaptionStyleTextSize) { + int text_size = 16; + int line_height = 24; + int bubble_height = 48; + int error_icon_height = 20; + ui::CaptionStyle caption_style; GetController()->UpdateCaptionStyle(base::nullopt); OnPartialTranscription("Hamsters' teeth never stop growing"); - EXPECT_EQ(textSize, GetLabel()->font_list().GetFontSize()); - EXPECT_EQ(textSize, GetTitle()->font_list().GetFontSize()); - EXPECT_EQ(lineHeight, GetLabel()->GetLineHeight()); - EXPECT_EQ(lineHeight, GetTitle()->GetLineHeight()); - EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubbleHeight); + EXPECT_EQ(text_size, GetLabel()->font_list().GetFontSize()); + EXPECT_EQ(text_size, GetTitle()->font_list().GetFontSize()); + EXPECT_EQ(line_height, GetLabel()->GetLineHeight()); + EXPECT_EQ(line_height, GetTitle()->GetLineHeight()); + EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubble_height); // Set the text size to 200%. - ui::CaptionStyle caption_style; caption_style.text_size = "200%"; GetController()->UpdateCaptionStyle(caption_style); - EXPECT_EQ(textSize * 2, GetLabel()->font_list().GetFontSize()); - EXPECT_EQ(textSize * 2, GetTitle()->font_list().GetFontSize()); - EXPECT_EQ(lineHeight * 2, GetLabel()->GetLineHeight()); - EXPECT_EQ(lineHeight * 2, GetTitle()->GetLineHeight()); - EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubbleHeight * 2); + EXPECT_EQ(text_size * 2, GetLabel()->font_list().GetFontSize()); + EXPECT_EQ(text_size * 2, GetTitle()->font_list().GetFontSize()); + EXPECT_EQ(line_height * 2, GetLabel()->GetLineHeight()); + EXPECT_EQ(line_height * 2, GetTitle()->GetLineHeight()); + EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubble_height * 2); // Set the text size to the empty string. caption_style.text_size = ""; GetController()->UpdateCaptionStyle(caption_style); - EXPECT_EQ(textSize, GetLabel()->font_list().GetFontSize()); - EXPECT_EQ(textSize, GetTitle()->font_list().GetFontSize()); - EXPECT_EQ(lineHeight, GetLabel()->GetLineHeight()); - EXPECT_EQ(lineHeight, GetTitle()->GetLineHeight()); - EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubbleHeight); + EXPECT_EQ(text_size, GetLabel()->font_list().GetFontSize()); + EXPECT_EQ(text_size, GetTitle()->font_list().GetFontSize()); + EXPECT_EQ(line_height, GetLabel()->GetLineHeight()); + EXPECT_EQ(line_height, GetTitle()->GetLineHeight()); + EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubble_height); // Set the text size to 50% !important. caption_style.text_size = "50% !important"; GetController()->UpdateCaptionStyle(caption_style); - EXPECT_EQ(textSize / 2, GetLabel()->font_list().GetFontSize()); - EXPECT_EQ(textSize / 2, GetTitle()->font_list().GetFontSize()); - EXPECT_EQ(lineHeight / 2, GetLabel()->GetLineHeight()); - EXPECT_EQ(lineHeight / 2, GetTitle()->GetLineHeight()); - EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubbleHeight / 2); + EXPECT_EQ(text_size / 2, GetLabel()->font_list().GetFontSize()); + EXPECT_EQ(text_size / 2, GetTitle()->font_list().GetFontSize()); + EXPECT_EQ(line_height / 2, GetLabel()->GetLineHeight()); + EXPECT_EQ(line_height / 2, GetTitle()->GetLineHeight()); + EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubble_height / 2); // Set the text size to a bad string. caption_style.text_size = "Ostriches can run up to 45mph"; GetController()->UpdateCaptionStyle(caption_style); - EXPECT_EQ(textSize, GetLabel()->font_list().GetFontSize()); - EXPECT_EQ(textSize, GetTitle()->font_list().GetFontSize()); - EXPECT_EQ(lineHeight, GetLabel()->GetLineHeight()); - EXPECT_EQ(lineHeight, GetTitle()->GetLineHeight()); - EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubbleHeight); + EXPECT_EQ(text_size, GetLabel()->font_list().GetFontSize()); + EXPECT_EQ(text_size, GetTitle()->font_list().GetFontSize()); + EXPECT_EQ(line_height, GetLabel()->GetLineHeight()); + EXPECT_EQ(line_height, GetTitle()->GetLineHeight()); + EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubble_height); - // Set the caption style to nullopt. - GetController()->UpdateCaptionStyle(base::nullopt); - EXPECT_EQ(textSize, GetLabel()->font_list().GetFontSize()); - EXPECT_EQ(textSize, GetTitle()->font_list().GetFontSize()); - EXPECT_EQ(lineHeight, GetLabel()->GetLineHeight()); - EXPECT_EQ(lineHeight, GetTitle()->GetLineHeight()); - EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubbleHeight); + // Set the caption style to a floating point percent. + caption_style.text_size = "62.5%"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(text_size * 0.625, GetLabel()->font_list().GetFontSize()); + EXPECT_EQ(text_size * 0.625, GetTitle()->font_list().GetFontSize()); + EXPECT_EQ(line_height * 0.625, GetLabel()->GetLineHeight()); + EXPECT_EQ(line_height * 0.625, GetTitle()->GetLineHeight()); + EXPECT_GT(GetBubble()->GetPreferredSize().height(), bubble_height * 0.625); // Set the error message. caption_style.text_size = "50%"; GetController()->UpdateCaptionStyle(caption_style); OnError(); - EXPECT_EQ(lineHeight / 2, GetErrorText()->GetLineHeight()); - EXPECT_EQ(errorIconHeight / 2, GetErrorIcon()->GetImageBounds().height()); - EXPECT_GT(GetBubble()->GetPreferredSize().height(), lineHeight / 2); + EXPECT_EQ(line_height / 2, GetErrorText()->GetLineHeight()); + EXPECT_EQ(error_icon_height / 2, GetErrorIcon()->GetImageBounds().height()); + EXPECT_GT(GetBubble()->GetPreferredSize().height(), line_height / 2); +} + +IN_PROC_BROWSER_TEST_F(CaptionBubbleControllerViewsTest, + UpdateCaptionStyleFontFamily) { +#if defined(OS_MAC) || defined(OS_WIN) + std::string default_font = "Roboto"; +#else + // Testing framework doesn't load all fonts, so Roboto is mapped to sans. + std::string default_font = "sans"; +#endif + + ui::CaptionStyle caption_style; + + GetController()->UpdateCaptionStyle(base::nullopt); + OnPartialTranscription("Koalas aren't bears: they are marsupials."); + EXPECT_EQ(default_font, + GetLabel()->font_list().GetPrimaryFont().GetFontName()); + EXPECT_EQ(default_font, + GetTitle()->font_list().GetPrimaryFont().GetFontName()); + EXPECT_EQ(default_font, + GetErrorText()->font_list().GetPrimaryFont().GetFontName()); + + // Set the font family to Helvetica. + caption_style.font_family = "Helvetica"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ("Helvetica", + GetLabel()->font_list().GetPrimaryFont().GetFontName()); + EXPECT_EQ("Helvetica", + GetTitle()->font_list().GetPrimaryFont().GetFontName()); + EXPECT_EQ("Helvetica", + GetErrorText()->font_list().GetPrimaryFont().GetFontName()); + + // Set the font family to the empty string. + caption_style.font_family = ""; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(default_font, + GetLabel()->font_list().GetPrimaryFont().GetFontName()); + EXPECT_EQ(default_font, + GetTitle()->font_list().GetPrimaryFont().GetFontName()); + EXPECT_EQ(default_font, + GetErrorText()->font_list().GetPrimaryFont().GetFontName()); + + // Set the font family to Helvetica !important. + caption_style.font_family = "Helvetica !important"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ("Helvetica", + GetLabel()->font_list().GetPrimaryFont().GetFontName()); + EXPECT_EQ("Helvetica", + GetTitle()->font_list().GetPrimaryFont().GetFontName()); + EXPECT_EQ("Helvetica", + GetErrorText()->font_list().GetPrimaryFont().GetFontName()); +} + +IN_PROC_BROWSER_TEST_F(CaptionBubbleControllerViewsTest, + UpdateCaptionStyleTextColor) { + SkColor default_color = SK_ColorWHITE; + ui::CaptionStyle caption_style; + + GetController()->UpdateCaptionStyle(base::nullopt); + OnPartialTranscription( + "Marsupials first evolved in South America about 100 million years ago."); + EXPECT_EQ(default_color, GetLabel()->GetEnabledColor()); + EXPECT_EQ(default_color, GetTitle()->GetEnabledColor()); + EXPECT_EQ(default_color, GetErrorText()->GetEnabledColor()); + + // Set the text color to red. + caption_style.text_color = "rgba(255,0,0,1)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SK_ColorRED, GetLabel()->GetEnabledColor()); + EXPECT_EQ(SK_ColorRED, GetTitle()->GetEnabledColor()); + EXPECT_EQ(SK_ColorRED, GetErrorText()->GetEnabledColor()); + + // Set the text color to the empty string. + caption_style.text_color = ""; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(default_color, GetLabel()->GetEnabledColor()); + EXPECT_EQ(default_color, GetTitle()->GetEnabledColor()); + EXPECT_EQ(default_color, GetErrorText()->GetEnabledColor()); + + // Set the text color to blue !important with 0.5 opacity. + caption_style.text_color = "rgba(0,0,255,0.5) !important"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SkColorSetA(SK_ColorBLUE, 127), GetLabel()->GetEnabledColor()); + EXPECT_EQ(SkColorSetA(SK_ColorBLUE, 127), GetTitle()->GetEnabledColor()); + EXPECT_EQ(SkColorSetA(SK_ColorBLUE, 127), GetErrorText()->GetEnabledColor()); + + // Set the text color to a bad string. + caption_style.text_color = "green"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(default_color, GetLabel()->GetEnabledColor()); + EXPECT_EQ(default_color, GetTitle()->GetEnabledColor()); + EXPECT_EQ(default_color, GetErrorText()->GetEnabledColor()); + + // Set the text color to green with spaces between the commas. + caption_style.text_color = "rgba(0, 255, 0, 1)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SK_ColorGREEN, GetLabel()->GetEnabledColor()); + EXPECT_EQ(SK_ColorGREEN, GetTitle()->GetEnabledColor()); + EXPECT_EQ(SK_ColorGREEN, GetErrorText()->GetEnabledColor()); + + // Set the text color to magenta with 0 opacity. + caption_style.text_color = "rgba(255,0,255,0)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(default_color, GetLabel()->GetEnabledColor()); + EXPECT_EQ(default_color, GetTitle()->GetEnabledColor()); + EXPECT_EQ(default_color, GetErrorText()->GetEnabledColor()); +} + +IN_PROC_BROWSER_TEST_F(CaptionBubbleControllerViewsTest, + UpdateCaptionStyleBackgroundColor) { + SkColor default_color = SkColorSetA(gfx::kGoogleGrey900, 230); + ui::CaptionStyle caption_style; + + GetController()->UpdateCaptionStyle(base::nullopt); + OnPartialTranscription("Most marsupials are nocturnal."); + EXPECT_EQ(default_color, GetBubble()->color()); + + // Set the window color to red with 0.5 opacity. + caption_style.window_color = "rgba(255,0,0,0.5)"; + caption_style.background_color = ""; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SkColorSetA(SK_ColorRED, 127), GetBubble()->color()); + + // Set the background color to blue. When no window color is supplied, the + // background color is applied to the caption bubble color. + caption_style.window_color = ""; + caption_style.background_color = "rgba(0,0,255,1)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SK_ColorBLUE, GetBubble()->color()); + + // Set both to the empty string. + caption_style.window_color = ""; + caption_style.background_color = ""; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(default_color, GetBubble()->color()); + + // Set the window color to green and the background color to majenta. The + // window color is applied to the caption bubble. + caption_style.window_color = "rgba(0,255,0,1)"; + caption_style.background_color = "rgba(255,0,255,1)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SK_ColorGREEN, GetBubble()->color()); + + // Set the window color to transparent and the background color to majenta. + // The non-transparent color is applied to the caption bubble. + caption_style.window_color = "rgba(0,255,0,0)"; + caption_style.background_color = "rgba(255,0,255,1)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SK_ColorMAGENTA, GetBubble()->color()); + + // Set the window color to yellow and the background color to transparent. + // The non-transparent color is applied to the caption bubble. + caption_style.window_color = "rgba(255,255,0,1)"; + caption_style.background_color = "rgba(0,0,0,0)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SK_ColorYELLOW, GetBubble()->color()); + + // Set both to transparent. + caption_style.window_color = "rgba(255,0,0,0)"; + caption_style.background_color = "rgba(0,255,0,0)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(default_color, GetBubble()->color()); + + // Set the background color to blue !important. + caption_style.window_color = ""; + caption_style.background_color = "rgba(0,0,255,1.0) !important"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SK_ColorBLUE, GetBubble()->color()); + + // Set the background color to a bad string. + caption_style.window_color = ""; + caption_style.background_color = "green"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(default_color, GetBubble()->color()); + + // Set the window color to green with spaces between the commas. + caption_style.window_color = ""; + caption_style.background_color = "rgba(0, 255, 0, 1)"; + GetController()->UpdateCaptionStyle(caption_style); + EXPECT_EQ(SK_ColorGREEN, GetBubble()->color()); } IN_PROC_BROWSER_TEST_F(CaptionBubbleControllerViewsTest,
diff --git a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc index 244b6d1..6485be3 100644 --- a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc +++ b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc
@@ -43,6 +43,7 @@ button_controller()->set_notify_action( views::ButtonController::NotifyAction::kOnPress); SetFlipCanvasOnPaintForRTLUI(false); + SetVectorIcons(kMediaToolbarButtonIcon, kMediaToolbarButtonTouchIcon); SetTooltipText( l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_ICON_TOOLTIP_TEXT)); GetViewAccessibility().OverrideHasPopup(ax::mojom::HasPopup::kDialog); @@ -127,13 +128,6 @@ observer.OnMediaButtonDisabled(); } -void MediaToolbarButtonView::UpdateIcon() { - const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); - const gfx::VectorIcon& icon = - touch_ui ? kMediaToolbarButtonTouchIcon : kMediaToolbarButtonIcon; - UpdateIconsWithStandardColors(icon); -} - void MediaToolbarButtonView::ButtonPressed() { if (MediaDialogView::IsShowing()) { MediaDialogView::HideDialog();
diff --git a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h index bf7f92fe..a9ea6d34 100644 --- a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h +++ b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h
@@ -37,9 +37,6 @@ void Enable() override; void Disable() override; - // ToolbarButton implementation. - void UpdateIcon() override; - private: void ButtonPressed();
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc index 1f5f7391..180edd3 100644 --- a/chrome/browser/ui/views/hung_renderer_view.cc +++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -12,6 +12,7 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/supports_user_data.h" #include "build/build_config.h" #include "chrome/browser/hang_monitor/hang_crash_dump.h" #include "chrome/browser/platform_util.h" @@ -45,28 +46,15 @@ #include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/widget/widget.h" -#if defined(OS_WIN) -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/shell_integration_win.h" -#include "ui/base/win/shell.h" -#include "ui/views/win/hwnd_util.h" -#endif - -#if defined(USE_AURA) -#include "ui/aura/window.h" -#endif - using content::WebContents; -HungRendererDialogView* HungRendererDialogView::g_instance_ = nullptr; - /////////////////////////////////////////////////////////////////////////////// // HungPagesTableModel, public: HungPagesTableModel::HungPagesTableModel(Delegate* delegate) : delegate_(delegate) {} -HungPagesTableModel::~HungPagesTableModel() {} +HungPagesTableModel::~HungPagesTableModel() = default; content::RenderWidgetHost* HungPagesTableModel::GetRenderWidgetHost() { return render_widget_host_; @@ -81,8 +69,6 @@ DCHECK(!hang_monitor_restarter.is_null()); DCHECK(!render_widget_host_); - DCHECK(!process_observer_.IsObservingSources()); - DCHECK(!widget_observer_.IsObservingSources()); DCHECK(tab_observers_.empty()); render_widget_host_ = render_widget_host; @@ -94,8 +80,8 @@ std::make_unique<WebContentsObserverImpl>(this, hung_contents)); } - process_observer_.Add(render_widget_host_->GetProcess()); - widget_observer_.Add(render_widget_host_); + process_observation_.Observe(render_widget_host_->GetProcess()); + widget_observation_.Observe(render_widget_host_); // The world is different. if (observer_) @@ -103,8 +89,8 @@ } void HungPagesTableModel::Reset() { - process_observer_.RemoveAll(); - widget_observer_.RemoveAll(); + process_observation_.Reset(); + widget_observation_.Reset(); tab_observers_.clear(); render_widget_host_ = nullptr; @@ -159,8 +145,8 @@ void HungPagesTableModel::RenderWidgetHostDestroyed( content::RenderWidgetHost* widget_host) { - DCHECK(widget_observer_.IsObserving(render_widget_host_)); - widget_observer_.Remove(widget_host); + DCHECK(widget_observation_.IsObservingSource(render_widget_host_)); + widget_observation_.Reset(); render_widget_host_ = nullptr; // Notify the delegate. @@ -190,10 +176,9 @@ } HungPagesTableModel::WebContentsObserverImpl::WebContentsObserverImpl( - HungPagesTableModel* model, WebContents* tab) - : content::WebContentsObserver(tab), - model_(model) { -} + HungPagesTableModel* model, + WebContents* tab) + : content::WebContentsObserver(tab), model_(model) {} void HungPagesTableModel::WebContentsObserverImpl::RenderViewHostChanged( content::RenderViewHost* old_host, @@ -224,20 +209,19 @@ /////////////////////////////////////////////////////////////////////////////// // HungRendererDialogView, public: -// static -HungRendererDialogView* HungRendererDialogView::Create( - gfx::NativeWindow context) { - if (!g_instance_) { - g_instance_ = new HungRendererDialogView; - views::DialogDelegate::CreateDialogWidget(g_instance_, context, nullptr); - } - return g_instance_; -} +namespace { -// static -HungRendererDialogView* HungRendererDialogView::GetInstance() { - return g_instance_; -} +constexpr int kDialogHolderUserDataKey = 0; + +struct DialogHolder : public base::SupportsUserData::Data { + explicit DialogHolder(HungRendererDialogView* dialog) : dialog(dialog) {} + + HungRendererDialogView* const dialog = nullptr; +}; + +static bool g_bypass_active_browser_requirement = false; + +} // namespace // static void HungRendererDialogView::Show( @@ -247,42 +231,50 @@ if (logging::DialogsAreSuppressed()) return; - gfx::NativeWindow window = - platform_util::GetTopLevel(contents->GetNativeView()); -#if defined(USE_AURA) - // Don't show the dialog if there is no root window for the renderer, because - // it's invisible to the user (happens when the renderer is for prerendering - // for example). - if (!window->GetRootWindow()) + if (IsShowingForWebContents(contents)) return; -#endif - HungRendererDialogView* view = HungRendererDialogView::Create(window); - view->ShowForWebContents(contents, render_widget_host, - std::move(hang_monitor_restarter)); + + // Only show for WebContents in a browser window. + if (!chrome::FindBrowserWithWebContents(contents)) + return; + + // Don't show the warning unless the foreground window is the frame. If the + // user has another window or application selected, activating ourselves is + // rude. Restart the hang monitor so that if that window comes to the + // foreground, the hang dialog will eventually show for it. + if (!platform_util::IsWindowActive( + platform_util::GetTopLevel(contents->GetNativeView())) && + !g_bypass_active_browser_requirement) { + hang_monitor_restarter.Run(); + return; + } + + HungRendererDialogView* view = CreateInstance( + contents, platform_util::GetTopLevel(contents->GetNativeView())); + view->ShowDialog(render_widget_host, std::move(hang_monitor_restarter)); } // static void HungRendererDialogView::Hide( WebContents* contents, content::RenderWidgetHost* render_widget_host) { - if (!logging::DialogsAreSuppressed() && HungRendererDialogView::GetInstance()) - HungRendererDialogView::GetInstance()->EndForWebContents( - contents, render_widget_host); + if (logging::DialogsAreSuppressed()) + return; + + DialogHolder* dialog_holder = static_cast<DialogHolder*>( + contents->GetUserData(&kDialogHolderUserDataKey)); + if (dialog_holder) + dialog_holder->dialog->EndDialog(render_widget_host); } // static -bool HungRendererDialogView::IsFrameActive(WebContents* contents) { - gfx::NativeWindow window = - platform_util::GetTopLevel(contents->GetNativeView()); - return platform_util::IsWindowActive(window); +bool HungRendererDialogView::IsShowingForWebContents(WebContents* contents) { + return contents->GetUserData(&kDialogHolderUserDataKey) != nullptr; } -HungRendererDialogView::HungRendererDialogView() { -#if defined(OS_WIN) - // Never use the custom frame when Aero Glass is disabled. See - // https://crbug.com/323278 - set_use_custom_frame(ui::win::IsAeroGlassEnabled()); -#endif +HungRendererDialogView::HungRendererDialogView(WebContents* web_contents) + : web_contents_(web_contents) { + SetModalType(ui::MODAL_TYPE_CHILD); set_margins(ChromeLayoutProvider::Get()->GetDialogInsetsForContentType( views::TEXT, views::CONTROL)); auto info_label = std::make_unique<views::Label>( @@ -339,63 +331,45 @@ hung_pages_table_->SetModel(nullptr); } -void HungRendererDialogView::ShowForWebContents( +// static +HungRendererDialogView* HungRendererDialogView::CreateInstance( WebContents* contents, - content::RenderWidgetHost* render_widget_host, - base::RepeatingClosure hang_monitor_restarter) { - DCHECK(contents && GetWidget()); + gfx::NativeWindow window) { + HungRendererDialogView* view = new HungRendererDialogView(contents); + constrained_window::CreateWebModalDialogViews(view, contents); + contents->SetUserData(&kDialogHolderUserDataKey, + std::make_unique<DialogHolder>(view)); - // Don't show the warning unless the foreground window is the frame, or this - // window (but still invisible). If the user has another window or - // application selected, activating ourselves is rude. - if (!IsFrameActive(contents) && - !platform_util::IsWindowActive(GetWidget()->GetNativeWindow())) - return; - - if (!GetWidget()->IsActive()) { - // Place the dialog over content's browser window, similar to modal dialogs. - Browser* browser = chrome::FindBrowserWithWebContents(contents); - if (browser) { - ChromeWebModalDialogManagerDelegate* manager = browser; - constrained_window::UpdateWidgetModalDialogPosition( - GetWidget(), manager->GetWebContentsModalDialogHost()); - } - - gfx::NativeWindow window = - platform_util::GetTopLevel(contents->GetNativeView()); - views::Widget* insert_after = - views::Widget::GetWidgetForNativeWindow(window); - if (insert_after) - GetWidget()->StackAboveWidget(insert_after); - -#if defined(OS_WIN) - // Group the hung renderer dialog with the browsers with the same profile. - Profile* profile = - Profile::FromBrowserContext(contents->GetBrowserContext()); - ui::win::SetAppIdForWindow( - shell_integration::win::GetAppUserModelIdForBrowser(profile->GetPath()), - views::HWNDForWidget(GetWidget())); -#endif - - // We only do this if the window isn't active (i.e. hasn't been shown yet, - // or is currently shown but deactivated for another WebContents). This is - // because this window is a singleton, and it's possible another active - // renderer may hang while this one is showing, and we don't want to reset - // the list of hung pages for a potentially unrelated renderer while this - // one is showing. - hung_pages_table_model_->InitForWebContents( - contents, render_widget_host, std::move(hang_monitor_restarter)); - - UpdateLabels(); - - GetWidget()->Show(); - } + return view; } -void HungRendererDialogView::EndForWebContents( - WebContents* contents, +// static +HungRendererDialogView* +HungRendererDialogView::GetInstanceForWebContentsForTests( + WebContents* contents) { + DialogHolder* dialog_holder = static_cast<DialogHolder*>( + contents->GetUserData(&kDialogHolderUserDataKey)); + if (dialog_holder) + return dialog_holder->dialog; + return nullptr; +} + +void HungRendererDialogView::ShowDialog( + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { + DCHECK(GetWidget()); + + hung_pages_table_model_->InitForWebContents( + web_contents_, render_widget_host, std::move(hang_monitor_restarter)); + + UpdateLabels(); + + constrained_window::ShowModalDialog(GetWidget()->GetNativeWindow(), + web_contents_); +} + +void HungRendererDialogView::EndDialog( content::RenderWidgetHost* render_widget_host) { - DCHECK(contents); if (hung_pages_table_model_->RowCount() == 0 || hung_pages_table_model_->GetRenderWidgetHost() == render_widget_host) { CloseDialogWithNoAction(); @@ -415,9 +389,24 @@ return false; } -void HungRendererDialogView::WindowClosing() { - // We are going to be deleted soon, so make sure our instance is destroyed. - g_instance_ = nullptr; +/////////////////////////////////////////////////////////////////////////////// +// HungRendererDialogView, HungPagesTableModel::Delegate overrides: + +void HungRendererDialogView::TabUpdated() { + RestartHangTimer(); +} + +void HungRendererDialogView::TabDestroyed() { + CloseDialogWithNoAction(); +} + +/////////////////////////////////////////////////////////////////////////////// +// HungRendererDialogView, private: + +void HungRendererDialogView::RestartHangTimer() { + // Start waiting again for responsiveness. + hung_pages_table_model_->RestartHangMonitorTimeout(); + ResetWebContentsAssociation(); } void HungRendererDialogView::ForceCrashHungRenderer() { @@ -434,28 +423,11 @@ rph->Shutdown(content::RESULT_CODE_HUNG); #endif } + ResetWebContentsAssociation(); } -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView, HungPagesTableModel::Delegate overrides: - -void HungRendererDialogView::TabUpdated() { - RestartHangTimer(); -} - -void HungRendererDialogView::TabDestroyed() { - CloseDialogWithNoAction(); -} - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView, views::View overrides: - -/////////////////////////////////////////////////////////////////////////////// -// HungRendererDialogView, private: - -void HungRendererDialogView::RestartHangTimer() { - // Start waiting again for responsiveness. - hung_pages_table_model_->RestartHangMonitorTimeout(); +void HungRendererDialogView::ResetWebContentsAssociation() { + web_contents_->RemoveUserData(&kDialogHolderUserDataKey); } void HungRendererDialogView::UpdateLabels() { @@ -474,8 +446,14 @@ // - While the dialog is active, [X] maps to restarting the hang timer, but // while closing we don't want that action. hung_pages_table_model_->Reset(); + ResetWebContentsAssociation(); GetWidget()->Close(); } +// static +void HungRendererDialogView::BypassActiveBrowserRequirementForTests() { + g_bypass_active_browser_requirement = true; +} + BEGIN_METADATA(HungRendererDialogView, views::DialogDelegateView) END_METADATA
diff --git a/chrome/browser/ui/views/hung_renderer_view.h b/chrome/browser/ui/views/hung_renderer_view.h index 3c92848..a35f2176 100644 --- a/chrome/browser/ui/views/hung_renderer_view.h +++ b/chrome/browser/ui/views/hung_renderer_view.h
@@ -10,7 +10,7 @@ #include "base/callback.h" #include "base/macros.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "components/favicon/content/content_favicon_driver.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host_observer.h" @@ -38,7 +38,7 @@ public: class Delegate { public: - // Notification when the model is updated (eg. new location) yet + // Notification when the model is updated (e.g. new location) yet // still hung. virtual void TabUpdated() = 0; @@ -46,7 +46,7 @@ virtual void TabDestroyed() = 0; protected: - virtual ~Delegate() {} + virtual ~Delegate() = default; }; explicit HungPagesTableModel(Delegate* delegate); @@ -127,11 +127,13 @@ // some more until the renderer process responds). base::RepeatingClosure hang_monitor_restarter_; - ScopedObserver<content::RenderProcessHost, content::RenderProcessHostObserver> - process_observer_{this}; + base::ScopedObservation<content::RenderProcessHost, + content::RenderProcessHostObserver> + process_observation_{this}; - ScopedObserver<content::RenderWidgetHost, content::RenderWidgetHostObserver> - widget_observer_{this}; + base::ScopedObservation<content::RenderWidgetHost, + content::RenderWidgetHostObserver> + widget_observation_{this}; }; // This class displays a dialog which contains information about a hung @@ -144,13 +146,6 @@ HungRendererDialogView(const HungRendererDialogView&) = delete; HungRendererDialogView& operator=(const HungRendererDialogView&) = delete; - // Factory function for creating an instance of the HungRendererDialogView - // class. At any given point only one instance can be active. - static HungRendererDialogView* Create(gfx::NativeWindow context); - - // Returns a pointer to the singleton instance if any. - static HungRendererDialogView* GetInstance(); - // Shows or hides the hung renderer dialog for the given WebContents. static void Show(content::WebContents* contents, content::RenderWidgetHost* render_widget_host, @@ -158,52 +153,81 @@ static void Hide(content::WebContents* contents, content::RenderWidgetHost* render_widget_host); - // Returns true if the frame is in the foreground. - static bool IsFrameActive(content::WebContents* contents); + // Returns true if there is an instance showing for the given WebContents. + static bool IsShowingForWebContents(content::WebContents* contents); views::TableView* table_for_testing() { return hung_pages_table_; } HungPagesTableModel* table_model_for_testing() { return hung_pages_table_model_.get(); } - virtual void ShowForWebContents( - content::WebContents* contents, - content::RenderWidgetHost* render_widget_host, - base::RepeatingClosure hang_monitor_restarter); - virtual void EndForWebContents(content::WebContents* contents, - content::RenderWidgetHost* render_widget_host); - // views::DialogDelegateView overrides: std::u16string GetWindowTitle() const override; bool ShouldShowCloseButton() const override; - void WindowClosing() override; // HungPagesTableModel::Delegate overrides: void TabUpdated() override; void TabDestroyed() override; - protected: - HungRendererDialogView(); - ~HungRendererDialogView() override; - - static HungRendererDialogView* g_instance_; - private: friend class HungRendererDialogViewBrowserTest; + explicit HungRendererDialogView(content::WebContents* web_contents); + ~HungRendererDialogView() override; + + // Creates an instance for the given WebContents and window. + static HungRendererDialogView* CreateInstance(content::WebContents* contents, + gfx::NativeWindow window); + + // Gets the instance, if any, for the given WebContents, or null if there is + // none. + static HungRendererDialogView* GetInstanceForWebContentsForTests( + content::WebContents* contents); + + // Shows or hides the dialog. Dispatched to by the `Show()` and `Hide()` + // static methods. + void ShowDialog(content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter); + void EndDialog(content::RenderWidgetHost* render_widget_host); + // Restart the hang timer, giving the page more time. void RestartHangTimer(); + + // Crashes the hung renderer. void ForceCrashHungRenderer(); + // Resets the association with the WebContents. + // + // TODO(avi): Calls to this are rather unfortunately scattered throughout the + // class, but there doesn't seem to be a place that would work for the three + // ways that the dialog can go away (the two buttons plus the external + // closing). Both the destructor and `WindowClosing()` functions are too late. + // Can it be wired in better? + void ResetWebContentsAssociation(); + + // Updates the labels and the button text of the dialog. Normally called only + // once when the render process first hangs, right before the dialog is shown. + // It is separated into its own function so that the browsertest's "show UI" + // functionality is able to fake a multi-page hang and force the UI to refresh + // as if multiple pages were legitimately hung. void UpdateLabels(); + // Causes the dialog to close with no action taken. Called when the page + // stops hanging by itself, or when the page or render process goes away. void CloseDialogWithNoAction(); + // Bypasses the requirement for the browser window to be active. Only used in + // tests. + static void BypassActiveBrowserRequirementForTests(); + + // The WebContents that this dialog was created for and is associated with. + content::WebContents* const web_contents_; + // The label describing the list. - views::Label* info_label_; + views::Label* info_label_ = nullptr; // Controls within the dialog box. - views::TableView* hung_pages_table_; + views::TableView* hung_pages_table_ = nullptr; // The model that provides the contents of the table that shows a list of // pages affected by the hang.
diff --git a/chrome/browser/ui/views/hung_renderer_view_browsertest.cc b/chrome/browser/ui/views/hung_renderer_view_browsertest.cc index dfd6205..e196e09 100644 --- a/chrome/browser/ui/views/hung_renderer_view_browsertest.cc +++ b/chrome/browser/ui/views/hung_renderer_view_browsertest.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/ui/tab_dialogs.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/test/test_browser_dialog.h" +#include "chrome/common/logging_chrome.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -26,7 +27,9 @@ // Interactive UI tests for the hung renderer (aka page unresponsive) dialog. class HungRendererDialogViewBrowserTest : public DialogBrowserTest { public: - HungRendererDialogViewBrowserTest() {} + HungRendererDialogViewBrowserTest() { + HungRendererDialogView::BypassActiveBrowserRequirementForTests(); + } // Normally the dialog only shows multiple WebContents when they're all part // of the same process, but that's hard to achieve in a test. @@ -50,11 +53,27 @@ base::DoNothing::Repeatedly()); if (name == "MultiplePages") { + HungRendererDialogView* view = + HungRendererDialogView::GetInstanceForWebContentsForTests( + web_contents); auto* web_contents2 = chrome::DuplicateTabAt(browser(), 0); - AddWebContents(HungRendererDialogView::GetInstance(), web_contents2); + AddWebContents(view, web_contents2); } } + HungRendererDialogView* CreateDialogView() { + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + + return HungRendererDialogView::CreateInstance( + web_contents, browser()->window()->GetNativeWindow()); + } + + void EndForWebContents(HungRendererDialogView* dialog, + content::WebContents* contents) { + dialog->EndDialog( + contents->GetMainFrame()->GetRenderViewHost()->GetWidget()); + } + private: DISALLOW_COPY_AND_ASSIGN(HungRendererDialogViewBrowserTest); }; @@ -74,15 +93,15 @@ // This is a regression test for https://crbug.com/855369. IN_PROC_BROWSER_TEST_F(HungRendererDialogViewBrowserTest, InactiveWindow) { + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + // Simulate creation of the dialog, without initializing or showing it yet. // This is what happens when HungRendererDialogView::ShowForWebContents // returns early if the frame or the dialog are not active. - HungRendererDialogView::Create(browser()->window()->GetNativeWindow()); - ASSERT_TRUE(HungRendererDialogView::GetInstance()); + CreateDialogView(); + ASSERT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents)); // Simulate the renderer becoming responsive again. - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); content::RenderWidgetHost* render_widget_host = web_contents->GetRenderWidgetHostView()->GetRenderWidgetHost(); content::WebContentsDelegate* web_contents_delegate = browser(); @@ -90,12 +109,12 @@ } IN_PROC_BROWSER_TEST_F(HungRendererDialogViewBrowserTest, ProcessClosed) { - HungRendererDialogView* dialog = - HungRendererDialogView::Create(browser()->window()->GetNativeWindow()); - ASSERT_TRUE(dialog); - auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + HungRendererDialogView* dialog = CreateDialogView(); + ASSERT_TRUE(dialog); + ASSERT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents)); + // The Hung Dialog requires window activation, window activations does not // work reliably in browser tests, especially in Mac because of the activation // policy for obtaining window key status is set to prohibited. Instead of @@ -111,11 +130,70 @@ dialog->table_for_testing()->GetViewAccessibility(); EXPECT_EQ(size_t{1}, view_accessibility.virtual_children().size()); - // Simulate an abrupt ending to webcontents. The accessibility tree for the - // TableView depends on the Hung Render View table model to send the right - // events. By checking the virtual tree, we can guarantee the sync is correct. - dialog->EndForWebContents( - web_contents, - web_contents->GetMainFrame()->GetRenderViewHost()->GetWidget()); + // Simulate an abrupt ending to the WebContents. The accessibility tree for + // the TableView depends on the Hung Render View table model to send the right + // events. By checking the virtual tree, we can guarantee the sync is + // correct. + EndForWebContents(dialog, web_contents); EXPECT_EQ(size_t{0}, view_accessibility.virtual_children().size()); } + +// This dialog used to be a singleton, so this is a basic test that it can now +// be shown on two different browser windows without crashing or obviously +// misbehaving. +IN_PROC_BROWSER_TEST_F(HungRendererDialogViewBrowserTest, TwoHungBrowsers) { + if (logging::DialogsAreSuppressed()) { + // If dialogs are suppressed then the hung renderer dialog can't be shown, + // and this test cannot pass, so bail. + LOG(ERROR) << "HungRendererDialogViewBrowserTest.TwoHungBrowsers cannot " + "run on bots, as hang dialogs are suppressed on them. You " + "will need to run this test locally to verify your fixes."; + return; + } + + Browser* browser1 = browser(); + content::WebContents* web_contents1 = + browser1->tab_strip_model()->GetActiveWebContents(); + content::RenderWidgetHost* widget_host1 = + web_contents1->GetMainFrame()->GetRenderViewHost()->GetWidget(); + + Browser* browser2 = + Browser::Create(Browser::CreateParams(browser1->profile(), true)); + chrome::NewTab(browser2); + content::WebContents* web_contents2 = + browser2->tab_strip_model()->GetActiveWebContents(); + content::RenderWidgetHost* widget_host2 = + web_contents2->GetMainFrame()->GetRenderViewHost()->GetWidget(); + + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); + HungRendererDialogView::Show(web_contents1, widget_host1, + base::DoNothing::Repeatedly()); + EXPECT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); + HungRendererDialogView::Show(web_contents2, widget_host2, + base::DoNothing::Repeatedly()); + EXPECT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); + HungRendererDialogView::Hide(web_contents1, widget_host1); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); + HungRendererDialogView::Hide(web_contents2, widget_host2); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); + + HungRendererDialogView::Show(web_contents1, widget_host1, + base::DoNothing::Repeatedly()); + EXPECT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); + HungRendererDialogView::Show(web_contents2, widget_host2, + base::DoNothing::Repeatedly()); + EXPECT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); + HungRendererDialogView::Hide(web_contents2, widget_host2); + EXPECT_TRUE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); + HungRendererDialogView::Hide(web_contents1, widget_host1); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents1)); + EXPECT_FALSE(HungRendererDialogView::IsShowingForWebContents(web_contents2)); +}
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc index 6a4a33b..a0b3b0d 100644 --- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc +++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc
@@ -43,6 +43,7 @@ : IDR_SAFETY_TIP_ILLUSTRATION_LIGHT; case security_state::SafetyTipStatus::kBadReputationIgnored: case security_state::SafetyTipStatus::kLookalikeIgnored: + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kBadKeyword: case security_state::SafetyTipStatus::kUnknown: case security_state::SafetyTipStatus::kNone:
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc index d74786445..948db06 100644 --- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
@@ -47,6 +47,7 @@ #include "content/public/common/referrer.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_navigation_observer.h" +#include "content/public/test/url_loader_interceptor.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" @@ -233,6 +234,7 @@ public testing::WithParamInterface<UIStatus> { protected: UIStatus ui_status() const { return GetParam(); } + virtual bool digital_asset_links_enabled() const { return false; } bool IsSuspiciousSiteWarningEnabled() const { return ui_status() == UIStatus::kEnabledWithDefaultFeatures || @@ -247,38 +249,52 @@ } void SetUp() override { + std::vector<base::test::ScopedFeatureList::FeatureAndParams> + enabled_features; + std::vector<base::Feature> disabled_features; + switch (ui_status()) { case UIStatus::kDisabled: - feature_list_.InitAndDisableFeature( - security_state::features::kSafetyTipUI); + disabled_features.push_back(security_state::features::kSafetyTipUI); break; case UIStatus::kEnabledWithDefaultFeatures: - feature_list_.InitAndEnableFeature( - security_state::features::kSafetyTipUI); + enabled_features.emplace_back(security_state::features::kSafetyTipUI, + base::FieldTrialParams()); break; case UIStatus::kEnabledWithSuspiciousSites: - feature_list_.InitWithFeaturesAndParameters( - {{security_state::features::kSafetyTipUI, - {{"suspicioussites", "true"}, - {"topsites", "false"}, - {"editdistance", "false"}, - {"editdistance_siteengagement", "false"}, - {"targetembedding", "false"}}}}, - {}); + enabled_features.emplace_back( + security_state::features::kSafetyTipUI, + base::FieldTrialParams({{"suspicioussites", "true"}, + {"topsites", "false"}, + {"editdistance", "false"}, + {"editdistance_siteengagement", "false"}, + {"targetembedding", "false"}})); break; case UIStatus::kEnabledWithAllFeatures: - feature_list_.InitWithFeaturesAndParameters( - {{security_state::features::kSafetyTipUI, - {{"suspicioussites", "true"}, - {"topsites", "true"}, - {"editdistance", "true"}, - {"editdistance_siteengagement", "true"}, - {"targetembedding", "true"}}}, - {lookalikes::features::kDetectTargetEmbeddingLookalikes, {}}}, - {}); + enabled_features.emplace_back( + security_state::features::kSafetyTipUI, + base::FieldTrialParams({{"suspicioussites", "true"}, + {"topsites", "true"}, + {"editdistance", "true"}, + {"editdistance_siteengagement", "true"}, + {"targetembedding", "true"}})); + enabled_features.emplace_back( + lookalikes::features::kDetectTargetEmbeddingLookalikes, + base::FieldTrialParams()); break; } + if (digital_asset_links_enabled()) { + enabled_features.emplace_back( + lookalikes::features::kLookalikeDigitalAssetLinks, + base::FieldTrialParams()); + } else { + disabled_features.push_back( + lookalikes::features::kLookalikeDigitalAssetLinks); + } + feature_list_.InitWithFeaturesAndParameters(enabled_features, + disabled_features); + reputation::InitializeSafetyTipConfig(); InProcessBrowserTest::SetUp(); } @@ -374,6 +390,7 @@ GetFormattedHostName(expected_safe_url))); break; + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kBadKeyword: case security_state::SafetyTipStatus::kUnknown: case security_state::SafetyTipStatus::kNone: @@ -522,6 +539,7 @@ IN_PROC_BROWSER_TEST_P(SafetyTipPageInfoBubbleViewBrowserTest, NoShowOnError) { auto kNavigatedUrl = embedded_test_server()->GetURL("site1.com", "/close-socket"); + reputation::SetSafetyTipBadRepPatterns({"site1.com/"}); NavigateToURL(browser(), kNavigatedUrl, WindowOpenDisposition::CURRENT_TAB); @@ -1388,3 +1406,154 @@ NavigateToURL(browser(), url, WindowOpenDisposition::CURRENT_TAB); EXPECT_FALSE(IsUIShowing()); } + +// Tests for Digital Asset Links for lookalike checks. +// TODO(meacer): Refactor the DAL code in LookalikeNavigationThrottle tests and +// reuse here. +class SafetyTipPageInfoBubbleViewDigitalAssetLinksBrowserTest + : public SafetyTipPageInfoBubbleViewBrowserTest { + protected: + struct TestSite { + std::string hostname; + std::string manifest; + }; + + bool digital_asset_links_enabled() const override { return true; } + + void TearDownOnMainThread() override { url_loader_interceptor_.reset(); } + + void SetUpManifests(const std::vector<TestSite>& sites) { + url_loader_interceptor_ = std::make_unique< + content::URLLoaderInterceptor>(base::BindRepeating( + &SafetyTipPageInfoBubbleViewDigitalAssetLinksBrowserTest::OnIntercept, + base::Unretained(this), sites)); + } + + static std::string MakeManifestWithTarget(const char* target_domain, + bool invalid = false) { + const char* const format = R"([{ + "relation": ["%s"], + "target": { + "namespace": "web", + "site": "https://%s" + } + }])"; + // Go through MakeURL to convert target_domain to punycode. + return base::StringPrintf(format, + (invalid ? "junkvalue" : "lookalikes/allowlist"), + MakeURL(target_domain).host().c_str()); + } + + private: + bool OnIntercept(const std::vector<TestSite>& sites, + content::URLLoaderInterceptor::RequestParams* params) { + for (const TestSite& site : sites) { + if (params->url_request.url == MakeManifestURL(site.hostname)) { + DCHECK(!site.manifest.empty()); + // Serve manifest contents: + std::string headers = + "HTTP/1.1 200 OK\nContent-Type: application/json; " + "charset=utf-8\n"; + content::URLLoaderInterceptor::WriteResponse(headers, site.manifest, + params->client.get()); + return true; + } + // Serve site's contents: + if (params->url_request.url == MakeURL(site.hostname)) { + content::URLLoaderInterceptor::WriteResponse( + "HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\n", + "<html>Test page</html>", params->client.get()); + return true; + } + } + return false; + } + + static GURL MakeManifestURL(const std::string& hostname) { + return GURL("https://" + hostname + "/.well-known/assetlinks.json"); + } + + static GURL MakeURL(const std::string& hostname) { + return GURL("https://" + hostname); + } + + std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_; +}; + +INSTANTIATE_TEST_SUITE_P( + All, + SafetyTipPageInfoBubbleViewDigitalAssetLinksBrowserTest, + ::testing::Values(UIStatus::kEnabledWithAllFeatures)); + +// Lookalike and target sites' manifests don't match each other. Show the UI. +// TODO(crbug.com/1191216): Check if there is already an existing manifest +// validation happening and ignore new validation requests. +IN_PROC_BROWSER_TEST_P(SafetyTipPageInfoBubbleViewDigitalAssetLinksBrowserTest, + ShowOnDigitalAssetLinkMismatch) { + if (!AreLookalikeWarningsEnabled()) { + return; + } + + const GURL kNavigatedUrl("https://gooogle.com"); + const GURL kTargetUrl("https://google.com"); + const std::vector<TestSite> sites{ + {kNavigatedUrl.host().c_str(), MakeManifestWithTarget("invalid.host")}, + {kTargetUrl.host().c_str(), MakeManifestWithTarget("invalid.host")}, + }; + SetUpManifests(sites); + + base::HistogramTester histograms; + + SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement); + SetEngagementScore(browser(), kTargetUrl, kHighEngagement); + NavigateToURL(browser(), kNavigatedUrl, WindowOpenDisposition::CURRENT_TAB); + ASSERT_TRUE(IsUIShowing()); + + histograms.ExpectTotalCount( + DigitalAssetLinkCrossValidator::kEventHistogramName, 2); + histograms.ExpectBucketCount( + DigitalAssetLinkCrossValidator::kEventHistogramName, + DigitalAssetLinkCrossValidator::Event::kStarted, 1); + histograms.ExpectBucketCount( + DigitalAssetLinkCrossValidator::kEventHistogramName, + DigitalAssetLinkCrossValidator::Event::kLookalikeManifestFailed, 1); +} + +// Same as ShowOnDigitalAssetLinkMismatch but with valid manifests. +// An edit distance match would normally display a Safety Tip, but the lookalike +// site properly allowlisted the target site so the Safety Tip is suppressed. +// TODO(crbug.com/1191216): Check if there is already an existing manifest +// validation happening and ignore new validation requests. +IN_PROC_BROWSER_TEST_P(SafetyTipPageInfoBubbleViewDigitalAssetLinksBrowserTest, + NoShowOnDigitalAssetLinkMatch) { + if (!AreLookalikeWarningsEnabled()) { + return; + } + + const GURL kNavigatedUrl("https://gooogle.com"); + const GURL kTargetUrl("https://google.com"); + const std::vector<TestSite> sites{ + {kNavigatedUrl.host().c_str(), + MakeManifestWithTarget(kTargetUrl.host().c_str())}, + {kTargetUrl.host().c_str(), + MakeManifestWithTarget(kNavigatedUrl.host().c_str())}, + }; + SetUpManifests(sites); + + base::HistogramTester histograms; + + SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement); + SetEngagementScore(browser(), kTargetUrl, kHighEngagement); + NavigateToURL(browser(), kNavigatedUrl, WindowOpenDisposition::CURRENT_TAB); + + ASSERT_FALSE(IsUIShowing()); + + histograms.ExpectTotalCount( + DigitalAssetLinkCrossValidator::kEventHistogramName, 2); + histograms.ExpectBucketCount( + DigitalAssetLinkCrossValidator::kEventHistogramName, + DigitalAssetLinkCrossValidator::Event::kStarted, 1); + histograms.ExpectBucketCount( + DigitalAssetLinkCrossValidator::kEventHistogramName, + DigitalAssetLinkCrossValidator::Event::kValidationSucceeded, 1); +}
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.cc b/chrome/browser/ui/views/profiles/profile_picker_view.cc index ed088cd0..65f773f3 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_view.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc
@@ -114,6 +114,12 @@ ->GetAvatarToolbarButton(); DCHECK(anchor_view); + // Don't show the customization bubble if a valid policy theme is set. + if (ThemeServiceFactory::GetForProfile(browser->profile()) + ->UsingPolicyTheme()) { + return; + } + if (ProfileCustomizationBubbleSyncController::CanThemeSyncStart( browser->profile())) { // For sync users, their profile color has not been applied yet. Call a @@ -216,6 +222,7 @@ : ToolbarButton(std::move(callback)) { SetTriggerableEventFlags(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON); + SetVectorIcons(vector_icons::kBackArrowIcon, kBackArrowTouchIcon); SetTooltipText(l10n_util::GetStringUTF16( IDS_PROFILE_PICKER_BACK_BUTTON_SIGN_IN_LABEL)); // Unlike toolbar buttons, this one should be focusable to make it @@ -226,14 +233,6 @@ SimpleBackButton(const SimpleBackButton&) = delete; SimpleBackButton& operator=(const SimpleBackButton&) = delete; ~SimpleBackButton() override = default; - - // ToolbarButton: - void UpdateIcon() override { - const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); - const gfx::VectorIcon* image = - touch_ui ? &kBackArrowTouchIcon : &vector_icons::kBackArrowIcon; - UpdateIconsWithStandardColors(*image); - } }; } // namespace @@ -781,8 +780,13 @@ // Initialize the WebUI page once we know it's committed. SyncConfirmationUI* sync_confirmation_ui = static_cast<SyncConfirmationUI*>( sign_in_->contents->GetWebUI()->GetController()); + + // The new profile theme may be overridden by an existing policy theme. This + // check ensures the correct theme is applied to the sync confirmation window. + auto* theme_service = ThemeServiceFactory::GetForProfile(sign_in_->profile); sync_confirmation_ui->InitializeMessageHandlerForCreationFlow( - sign_in_->profile_color); + theme_service->UsingPolicyTheme() ? theme_service->GetPolicyThemeColor() + : sign_in_->profile_color); } void ProfilePickerView::SwitchToProfileSwitch(
diff --git a/chrome/browser/ui/views/sharing/sharing_browsertest.cc b/chrome/browser/ui/views/sharing/sharing_browsertest.cc index 279fa02..fc3261b 100644 --- a/chrome/browser/ui/views/sharing/sharing_browsertest.cc +++ b/chrome/browser/ui/views/sharing/sharing_browsertest.cc
@@ -152,7 +152,7 @@ original_device.last_updated_timestamp(), original_device.pulse_interval(), original_device.send_tab_to_self_receiving_enabled(), - original_device.sharing_info(), + original_device.sharing_info(), original_device.paask_info(), original_device.fcm_registration_token(), original_device.interested_data_types()); fake_device_info_tracker_.Add(fake_device.get());
diff --git a/chrome/browser/ui/views/tab_dialogs_views.cc b/chrome/browser/ui/views/tab_dialogs_views.cc index 7eb9c1a..c34a5a05 100644 --- a/chrome/browser/ui/views/tab_dialogs_views.cc +++ b/chrome/browser/ui/views/tab_dialogs_views.cc
@@ -56,7 +56,7 @@ } bool TabDialogsViews::IsShowingHungRendererDialog() { - return HungRendererDialogView::GetInstance(); + return HungRendererDialogView::IsShowingForWebContents(web_contents_); } void TabDialogsViews::ShowProfileSigninConfirmation(
diff --git a/chrome/browser/ui/views/toolbar/back_forward_button.cc b/chrome/browser/ui/views/toolbar/back_forward_button.cc index bb7bb5ca6..b15b929 100644 --- a/chrome/browser/ui/views/toolbar/back_forward_button.cc +++ b/chrome/browser/ui/views/toolbar/back_forward_button.cc
@@ -24,18 +24,19 @@ direction == Direction::kBack ? BackForwardMenuModel::ModelType::kBackward : BackForwardMenuModel::ModelType::kForward), - browser->tab_strip_model()), - direction_(direction) { + browser->tab_strip_model()) { SetHideInkDropWhenShowingContextMenu(false); SetTriggerableEventFlags(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON); - if (direction_ == Direction::kBack) { + if (direction == Direction::kBack) { + SetVectorIcons(vector_icons::kBackArrowIcon, kBackArrowTouchIcon); SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_BACK)); SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK)); GetViewAccessibility().OverrideDescription( l10n_util::GetStringUTF8(IDS_ACCDESCRIPTION_BACK)); SetID(VIEW_ID_BACK_BUTTON); } else { + SetVectorIcons(vector_icons::kForwardArrowIcon, kForwardArrowTouchIcon); SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_FORWARD)); SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_FORWARD)); GetViewAccessibility().OverrideDescription( @@ -46,17 +47,5 @@ BackForwardButton::~BackForwardButton() = default; -void BackForwardButton::UpdateIcon() { - const gfx::VectorIcon* image = nullptr; - const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); - if (direction_ == Direction::kBack) { - image = touch_ui ? &kBackArrowTouchIcon : &vector_icons::kBackArrowIcon; - } else { - image = - touch_ui ? &kForwardArrowTouchIcon : &vector_icons::kForwardArrowIcon; - } - UpdateIconsWithStandardColors(*image); -} - BEGIN_METADATA(BackForwardButton, ToolbarButton) END_METADATA
diff --git a/chrome/browser/ui/views/toolbar/back_forward_button.h b/chrome/browser/ui/views/toolbar/back_forward_button.h index 2add99c..bf5b2fc 100644 --- a/chrome/browser/ui/views/toolbar/back_forward_button.h +++ b/chrome/browser/ui/views/toolbar/back_forward_button.h
@@ -22,12 +22,6 @@ BackForwardButton(const BackForwardButton&) = delete; BackForwardButton& operator=(const BackForwardButton&) = delete; ~BackForwardButton() override; - - // ToolbarButton: - void UpdateIcon() override; - - private: - Direction direction_; }; #endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_BACK_FORWARD_BUTTON_H_
diff --git a/chrome/browser/ui/views/toolbar/home_button.cc b/chrome/browser/ui/views/toolbar/home_button.cc index 10c88c8..c01e235 100644 --- a/chrome/browser/ui/views/toolbar/home_button.cc +++ b/chrome/browser/ui/views/toolbar/home_button.cc
@@ -152,6 +152,7 @@ : ToolbarButton(std::move(callback)), browser_(browser) { SetTriggerableEventFlags(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON); + SetVectorIcons(kNavigateHomeIcon, kNavigateHomeTouchIcon); SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_HOME)); SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_HOME)); SetID(VIEW_ID_HOME_BUTTON); @@ -198,12 +199,5 @@ return ui::mojom::DragOperation::kNone; } -void HomeButton::UpdateIcon() { - const gfx::VectorIcon& home_image = ui::TouchUiController::Get()->touch_ui() - ? kNavigateHomeTouchIcon - : kNavigateHomeIcon; - UpdateIconsWithStandardColors(home_image); -} - BEGIN_METADATA(HomeButton, ToolbarButton) END_METADATA
diff --git a/chrome/browser/ui/views/toolbar/home_button.h b/chrome/browser/ui/views/toolbar/home_button.h index aecb751..d92b84a0 100644 --- a/chrome/browser/ui/views/toolbar/home_button.h +++ b/chrome/browser/ui/views/toolbar/home_button.h
@@ -29,7 +29,6 @@ int OnDragUpdated(const ui::DropTargetEvent& event) override; ui::mojom::DragOperation OnPerformDrop( const ui::DropTargetEvent& event) override; - void UpdateIcon() override; private: Browser* const browser_;
diff --git a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc index d947a7ab..2365442 100644 --- a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc
@@ -54,16 +54,12 @@ true)) { contents_wrapper_->ReloadWebContents(); + SetVectorIcon(kReadLaterIcon); SetTooltipText(l10n_util::GetStringUTF16(IDS_READ_LATER_TITLE)); } ReadLaterToolbarButton::~ReadLaterToolbarButton() = default; -void ReadLaterToolbarButton::OnThemeChanged() { - ToolbarButton::OnThemeChanged(); - UpdateIconsWithStandardColors(kReadLaterIcon); -} - void ReadLaterToolbarButton::ButtonPressed() { BrowserView* const browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
diff --git a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.h b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.h index 2b1d4ca..1db6a0e3 100644 --- a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.h +++ b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.h
@@ -20,9 +20,6 @@ ReadLaterToolbarButton& operator=(const ReadLaterToolbarButton&) = delete; ~ReadLaterToolbarButton() override; - // ToolbarButton: - void OnThemeChanged() override; - private: void ButtonPressed();
diff --git a/chrome/browser/ui/views/toolbar/reload_button.cc b/chrome/browser/ui/views/toolbar/reload_button.cc index af6bd549..69926323 100644 --- a/chrome/browser/ui/views/toolbar/reload_button.cc +++ b/chrome/browser/ui/views/toolbar/reload_button.cc
@@ -27,17 +27,6 @@ #include "ui/views/metrics.h" #include "ui/views/widget/widget.h" -namespace { - -const gfx::VectorIcon& GetIconForMode(bool is_reload) { - if (ui::TouchUiController::Get()->touch_ui()) - return is_reload ? kReloadTouchIcon : kNavigateStopTouchIcon; - - return is_reload ? vector_icons::kReloadIcon : kNavigateStopIcon; -} - -} // namespace - // ReloadButton --------------------------------------------------------------- ReloadButton::ReloadButton(CommandUpdater* command_updater) @@ -49,6 +38,7 @@ double_click_timer_delay_( base::TimeDelta::FromMilliseconds(views::GetDoubleClickInterval())), mode_switch_timer_delay_(base::TimeDelta::FromMilliseconds(1350)) { + SetVisibleMode(Mode::kReload); SetTriggerableEventFlags(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON); SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_RELOAD)); @@ -68,8 +58,7 @@ : (visible_mode_ != Mode::kStop))) { double_click_timer_.Stop(); mode_switch_timer_.Stop(); - visible_mode_ = mode; - UpdateIcon(); + SetVisibleMode(mode); SetEnabled(true); // We want to disable the button if we're preventing a change from stop to @@ -97,20 +86,6 @@ menu_enabled_ = enable; } -void ReloadButton::OnThemeChanged() { - ToolbarButton::OnThemeChanged(); - UpdateIcon(); -} - -void ReloadButton::UpdateIcon() { - // There's no reason to make graphical changes when we're not yet in a - // Widget. This function will be called again after widget addition. - if (!GetWidget()) - return; - - UpdateIconsWithStandardColors(GetIconForMode(visible_mode_ == Mode::kReload)); -} - void ReloadButton::OnMouseExited(const ui::MouseEvent& event) { ToolbarButton::OnMouseExited(event); if (!IsMenuShowing()) @@ -173,6 +148,18 @@ return menu_model; } +void ReloadButton::SetVisibleMode(Mode mode) { + visible_mode_ = mode; + switch (mode) { + case Mode::kReload: + SetVectorIcons(vector_icons::kReloadIcon, kReloadTouchIcon); + break; + case Mode::kStop: + SetVectorIcons(kNavigateStopIcon, kNavigateStopTouchIcon); + break; + } +} + void ReloadButton::ButtonPressed(const ui::Event& event) { ClearPendingMenu();
diff --git a/chrome/browser/ui/views/toolbar/reload_button.h b/chrome/browser/ui/views/toolbar/reload_button.h index fed211d2..092d026b 100644 --- a/chrome/browser/ui/views/toolbar/reload_button.h +++ b/chrome/browser/ui/views/toolbar/reload_button.h
@@ -45,16 +45,12 @@ bool GetMenuEnabled() const; void SetMenuEnabled(bool enable); - // views::View: - void OnThemeChanged() override; - // ToolbarButton: void OnMouseExited(const ui::MouseEvent& event) override; std::u16string GetTooltipText(const gfx::Point& p) const override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; bool ShouldShowMenu() override; void ShowDropDownMenu(ui::MenuSourceType source_type) override; - void UpdateIcon() override; // ui::SimpleMenuModel::Delegate: bool IsCommandIdChecked(int command_id) const override; @@ -69,13 +65,14 @@ std::unique_ptr<ui::SimpleMenuModel> CreateMenuModel(); + void SetVisibleMode(Mode mode); + void ButtonPressed(const ui::Event& event); void ExecuteBrowserCommand(int command, int event_flags); void OnDoubleClickTimer(); void OnStopToReloadTimer(); - void OnLongLoadTimer(); base::OneShotTimer double_click_timer_;
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc index 0c8fb15..2743977 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -320,6 +320,25 @@ ui::ImageModel::FromVectorIcon(icon, disabled_color)); } +void ToolbarButton::SetVectorIcon(const gfx::VectorIcon& icon) { + SetVectorIcons(icon, icon); +} + +void ToolbarButton::SetVectorIcons(const gfx::VectorIcon& icon, + const gfx::VectorIcon& touch_icon) { + vector_icons_.emplace(VectorIcons{icon, touch_icon}); + if (GetThemeProvider()) + UpdateIcon(); +} + +void ToolbarButton::UpdateIcon() { + if (vector_icons_) { + UpdateIconsWithStandardColors(ui::TouchUiController::Get()->touch_ui() + ? vector_icons_->touch_icon + : vector_icons_->icon); + } +} + void ToolbarButton::UpdateIconsWithStandardColors(const gfx::VectorIcon& icon) { UpdateIconsWithColors(icon, GetForegroundColor(ButtonState::STATE_NORMAL), GetForegroundColor(ButtonState::STATE_HOVERED),
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.h b/chrome/browser/ui/views/toolbar/toolbar_button.h index 0db9dd4..30b21418 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.h +++ b/chrome/browser/ui/views/toolbar/toolbar_button.h
@@ -14,6 +14,7 @@ #include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/animation/slide_animation.h" #include "ui/gfx/geometry/point.h" +#include "ui/gfx/vector_icon_types.h" #include "ui/views/context_menu_controller.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/metadata/metadata_header_macros.h" @@ -79,13 +80,23 @@ void ClearPendingMenu(); bool IsMenuShowing() const; + // Sets the button's vector icon. This icon uses the default colors and are + // automatically updated on theme changes. + void SetVectorIcon(const gfx::VectorIcon& icon); + + // Sets an icon and touch-mode icon for this button. + // TODO(pbos): Investigate if touch-mode icons are just different-size ones + // that can be folded into the same .icon file as different CANVAS_DIMENSIONS. + void SetVectorIcons(const gfx::VectorIcon& icon, + const gfx::VectorIcon& touch_icon); + // Updates the images using the given icon and the default colors returned by // GetForegroundColor(). void UpdateIconsWithStandardColors(const gfx::VectorIcon& icon); // Updates the icon images and colors as necessary. Should be called any time // icon state changes, e.g. in response to theme or touch mode changes. - virtual void UpdateIcon() {} + virtual void UpdateIcon(); // Gets/Sets |layout_insets_|, see comment there. base::Optional<gfx::Insets> GetLayoutInsets() const; @@ -220,6 +231,14 @@ gfx::SlideAnimation highlight_color_animation_; }; + // TODO(pbos): See if VECTOR_ICON_TEMPLATE_CC can create constexpr VectorIcons + // so SetVectorIcon and friends can use constexpr to avoid potential lifetime + // problems if runtime-created gfx::VectorIcons were to become a thing. + struct VectorIcons { + const gfx::VectorIcon& icon; + const gfx::VectorIcon& touch_icon; + }; + void TouchUiChanged(); // Clears the current highlight, i.e. it sets the label to an empty string and @@ -269,6 +288,10 @@ // Menu runner to display drop down menu. std::unique_ptr<views::MenuRunner> menu_runner_; + // Vector icons for the ToolbarButton. The icon is chosen based on touch-ui. + // Reacts to theme changes using default colors. + base::Optional<VectorIcons> vector_icons_; + // Layout insets to use. This is used when the ToolbarButton is not actually // hosted inside the toolbar. If not supplied, // |GetLayoutInsets(TOOLBAR_BUTTON)| is used instead which is not appropriate
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder_browsertest.cc b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder_browsertest.cc index f841a25..50ecd4d7 100644 --- a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder_browsertest.cc +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_metrics_recorder_browsertest.cc
@@ -43,9 +43,7 @@ } void CloseAddSupervisionDialog() { - bool out_close_dialog = - AddSupervisionDialog::GetInstance()->DeprecatedOnDialogCloseRequested(); - EXPECT_TRUE(out_close_dialog); + AddSupervisionDialog::GetInstance()->OnDialogWillClose(); CloseNowForTesting(); }
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.cc b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.cc index e8ad047..644ccb0 100644 --- a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.cc +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.cc
@@ -126,11 +126,10 @@ return !showing_confirm_dialog; } -bool AddSupervisionDialog::DeprecatedOnDialogCloseRequested() { +void AddSupervisionDialog::OnDialogWillClose() { // Record UMA metric that user has closed the Add Supervision dialog. AddSupervisionMetricsRecorder::GetInstance()->RecordAddSupervisionEnrollment( AddSupervisionMetricsRecorder::EnrollmentState::kClosed); - return true; } bool AddSupervisionDialog::ShouldCloseDialogOnEscape() const {
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h index 9677c38..9238359 100644 --- a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h
@@ -49,7 +49,7 @@ ui::ModalType GetDialogModalType() const override; void GetDialogSize(gfx::Size* size) const override; bool OnDialogCloseRequested() override; - bool DeprecatedOnDialogCloseRequested() override; + void OnDialogWillClose() override; bool ShouldCloseDialogOnEscape() const override; protected:
diff --git a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc index 0b39449b..6a6b2f2 100644 --- a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc
@@ -97,6 +97,8 @@ {"networkListItemNotConnected", IDS_NETWORK_LIST_NOT_CONNECTED}, {"networkListItemNoNetwork", IDS_NETWORK_LIST_NO_NETWORK}, {"networkListItemDownload", IDS_NETWORK_LIST_ITEM_DOWNLOAD}, + {"networkListItemDownloadA11yLabel", + IDS_NETWORK_LIST_ITEM_DOWNLOAD_A11Y_LABEL}, {"networkListItemUnlock", IDS_NETWORK_LIST_ITEM_UNLOCK}, {"networkListItemUnlockA11YLabel", IDS_NETWORK_LIST_ITEM_UNLOCK_A11Y_LABEL}, {"networkListItemAddingProfile", IDS_NETWORK_LIST_ITEM_ADDING_PROFILE},
diff --git a/chrome/browser/ui/webui/customize_themes/chrome_customize_themes_handler.cc b/chrome/browser/ui/webui/customize_themes/chrome_customize_themes_handler.cc index 1bf52c65..f248dc8 100644 --- a/chrome/browser/ui/webui/customize_themes/chrome_customize_themes_handler.cc +++ b/chrome/browser/ui/webui/customize_themes/chrome_customize_themes_handler.cc
@@ -110,12 +110,12 @@ const ui::ThemeProvider& theme_provider = ThemeService::GetThemeProviderForProfile(profile_); - if (theme_service_->UsingDefaultTheme() || theme_service_->UsingSystemTheme()) { theme->type = customize_themes::mojom::ThemeType::kDefault; theme->info = customize_themes::mojom::ThemeInfo::NewChromeThemeId( chrome_colors::kDefaultColorId); + theme->is_forced = false; } else if (theme_service_->UsingExtensionTheme()) { theme->type = customize_themes::mojom::ThemeType::kThirdParty; auto info = customize_themes::mojom::ThirdPartyThemeInfo::New(); @@ -129,10 +129,13 @@ } theme->info = customize_themes::mojom::ThemeInfo::NewThirdPartyThemeInfo( std::move(info)); + theme->is_forced = false; } else { DCHECK(theme_service_->UsingAutogeneratedTheme()); + theme->is_forced = theme_service_->UsingPolicyTheme(); int color_id = chrome_colors::ChromeColorsService::GetColorId( - theme_service_->GetAutogeneratedThemeColor()); + theme->is_forced ? theme_service_->GetPolicyThemeColor() + : theme_service_->GetAutogeneratedThemeColor()); if (color_id != chrome_colors::kOtherColorId) { theme->type = customize_themes::mojom::ThemeType::kChrome; theme->info =
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc index d915fbd..13f1962 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -202,6 +202,9 @@ // Theme. {"themeCreatedBy", IDS_NEW_TAB_ATTRIBUTION_INTRO}, + {"themeManagedDialogTitle", IDS_NTP_THEME_MANAGED_DIALOG_TITLE}, + {"themeManagedDialogBody", IDS_NTP_THEME_MANAGED_DIALOG_BODY}, + {"ok", IDS_OK}, // Modules. {"dismissModuleToastMessage", IDS_NTP_MODULES_DISMISS_TOAST_MESSAGE},
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc index b35cc79..0330200 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
@@ -345,6 +345,11 @@ ::switches::kEnableExperimentalAccessibilitySwitchAccessText); } +bool IsSwitchAccessPointScanningEnabled() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kEnableSwitchAccessPointScanning); +} + bool IsSwitchAccessSetupGuideAllowed() { return base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kEnableExperimentalAccessibilitySwitchAccessSetupGuide); @@ -584,6 +589,8 @@ IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_SPEED_LABEL}, {"switchAccessAutoScanKeyboardSpeedLabel", IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_KEYBOARD_SPEED_LABEL}, + {"switchAccessPointScanSpeedLabel", + IDS_SETTINGS_SWITCH_ACCESS_POINT_SCAN_SPEED_LABEL}, {"durationInSeconds", IDS_SETTINGS_DURATION_IN_SECONDS}, {"manageAccessibilityFeatures", IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES}, @@ -662,6 +669,9 @@ "showExperimentalAccessibilitySwitchAccessImprovedTextInput", IsSwitchAccessTextAllowed()); + html_source->AddBoolean("isSwitchAccessPointScanningEnabled", + IsSwitchAccessPointScanningEnabled()); + html_source->AddBoolean("showSwitchAccessSetupGuide", IsSwitchAccessSetupGuideAllowed());
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 877c653..99af544 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1219,6 +1219,10 @@ {"defaultThemeLabel", IDS_NTP_CUSTOMIZE_DEFAULT_LABEL}, {"thirdPartyThemeDescription", IDS_NTP_CUSTOMIZE_3PT_THEME_DESC}, {"uninstallThirdPartyThemeButton", IDS_NTP_CUSTOMIZE_3PT_THEME_UNINSTALL}, + + // Managed theme dialog strings: + {"themeManagedDialogTitle", IDS_NTP_THEME_MANAGED_DIALOG_TITLE}, + {"themeManagedDialogBody", IDS_NTP_THEME_MANAGED_DIALOG_BODY}, #endif {"deleteProfileWarningExpandA11yLabel", IDS_SETTINGS_SYNC_DISCONNECT_EXPAND_ACCESSIBILITY_LABEL},
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index f103c24..9a0b312 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -39,6 +39,8 @@ #include "chrome/browser/signin/local_auth.h" #include "chrome/browser/signin/signin_promo.h" #include "chrome/browser/signin/signin_util.h" +#include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" @@ -303,7 +305,10 @@ } SetProfileName(profile->GetPath(), profile_name); Browser* browser = chrome::FindBrowserWithProfile(profile); - if (browser) { + + // Don't show the customization bubble if a valid policy theme is set. + if (browser && + !ThemeServiceFactory::GetForProfile(profile)->UsingPolicyTheme()) { ApplyProfileColorAndShowCustomizationBubbleWhenNoValueSynced( browser, GenerateNewProfileColor().color); }
diff --git a/chrome/browser/webauthn/android/cable_module_android.cc b/chrome/browser/webauthn/android/cable_module_android.cc index e73c6236b..1334eb17 100644 --- a/chrome/browser/webauthn/android/cable_module_android.cc +++ b/chrome/browser/webauthn/android/cable_module_android.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/webauthn/android/cable_module_android.h" + #include "base/bind.h" #include "base/no_destructor.h" #include "chrome/browser/browser_process.h" @@ -65,6 +67,12 @@ GetRegistration(); } +base::Optional<syncer::DeviceInfo::PhoneAsASecurityKeyInfo> +GetSyncDataIfRegistered() { + // Not yet implemented. + return base::nullopt; +} + } // namespace authenticator } // namespace webauthn
diff --git a/chrome/browser/webauthn/android/cable_module_android.h b/chrome/browser/webauthn/android/cable_module_android.h index 454cdf7..7a37ae3 100644 --- a/chrome/browser/webauthn/android/cable_module_android.h +++ b/chrome/browser/webauthn/android/cable_module_android.h
@@ -5,6 +5,9 @@ #ifndef CHROME_BROWSER_WEBAUTHN_ANDROID_CABLE_MODULE_ANDROID_H_ #define CHROME_BROWSER_WEBAUTHN_ANDROID_CABLE_MODULE_ANDROID_H_ +#include "base/optional.h" +#include "components/sync_device_info/device_info.h" + namespace webauthn { namespace authenticator { @@ -15,7 +18,14 @@ // dropped.) void RegisterForCloudMessages(); +// GetSyncDataIfRegistered returns a structure containing values to advertise in +// Sync that will let other Chrome instances contact this device to perform +// security key transactions, or it returns |nullopt| if that information is +// not yet ready. +base::Optional<syncer::DeviceInfo::PhoneAsASecurityKeyInfo> +GetSyncDataIfRegistered(); + } // namespace authenticator } // namespace webauthn -#endif +#endif // CHROME_BROWSER_WEBAUTHN_ANDROID_CABLE_MODULE_ANDROID_H_
diff --git a/chrome/browser/webshare/win/fake_data_transfer_manager_interop.cc b/chrome/browser/webshare/win/fake_data_transfer_manager_interop.cc index 7701af8d0..f7982903 100644 --- a/chrome/browser/webshare/win/fake_data_transfer_manager_interop.cc +++ b/chrome/browser/webshare/win/fake_data_transfer_manager_interop.cc
@@ -6,9 +6,9 @@ #include "base/callback.h" #include "base/callback_helpers.h" -#include "base/task/post_task.h" #include "chrome/browser/webshare/win/fake_data_transfer_manager.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" namespace webshare { @@ -65,8 +65,8 @@ std::move(it->second->GetDataRequestedInvoker()).Run(); return E_FAIL; case ShowShareUIForWindowBehavior::ScheduleEvent: - EXPECT_TRUE(base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - it->second->GetDataRequestedInvoker())); + EXPECT_TRUE(content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, it->second->GetDataRequestedInvoker())); return S_OK; case ShowShareUIForWindowBehavior::SucceedWithoutAction: return S_OK;
diff --git a/chrome/browser/webshare/win/share_operation.cc b/chrome/browser/webshare/win/share_operation.cc index 2927a9a..990e6e06 100644 --- a/chrome/browser/webshare/win/share_operation.cc +++ b/chrome/browser/webshare/win/share_operation.cc
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "base/win/core_winrt_util.h" #include "base/win/post_async_results.h" #include "base/win/scoped_hstring.h" @@ -16,6 +15,7 @@ #include "chrome/browser/webshare/share_service_impl.h" #include "chrome/browser/webshare/win/show_share_ui_for_window_operation.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "net/base/net_errors.h" #include "storage/browser/blob/blob_data_handle.h" @@ -250,8 +250,8 @@ base::OnceCallback<void()> on_complete) { stream_ = ComPtr<IOutputStream>(stream); on_complete_ = std::move(on_complete); - if (!base::PostTask( - FROM_HERE, {content::BrowserThread::IO}, + if (!content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&OutputStreamWriteOperation::WriteStreamOnIOThread, weak_factory_.GetWeakPtr()))) Complete();
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index e7061b42..2eaa8fc 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1616673495-b84a57e9b11103babbbcecb4fe3025603a200342.profdata +chrome-linux-master-1616688932-8908de30e8d4928a4b6ebe72cfae8aa5c926495b.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 7973264..555e58a4 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1614408593-7dfbbce046043e8e6d4f3696865e54c4eaf79174.profdata +chrome-win32-master-1616688932-0cc7d689b3cb3193e016f80eb9aca2a6f2a5db92.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index f82b56d0..ec8924f7 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1614408593-726e9c9aad1d48380ce819ccaf50f12f0726947c.profdata +chrome-win64-master-1616684217-b206821e8155e9e063c7043539d22db342483e7a.profdata
diff --git a/chrome/common/channel_info_win.cc b/chrome/common/channel_info_win.cc index ab5abe4..f273133 100644 --- a/chrome/common/channel_info_win.cc +++ b/chrome/common/channel_info_win.cc
@@ -14,9 +14,8 @@ std::string GetChannelName(WithExtendedStable with_extended_stable) { #if BUILDFLAG(GOOGLE_CHROME_BRANDING) - std::wstring channel((with_extended_stable && IsExtendedStableChannel()) - ? L"extended" - : install_static::GetChromeChannelName()); + std::wstring channel( + install_static::GetChromeChannelName(with_extended_stable.value())); #if defined(DCHECK_IS_CONFIGURABLE) // Adorn the channel when DCHECKs are baked into the build, as there will be // a performance hit. See https://crbug.com/812058 for details.
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index f01b11a8..c7d843b 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -481,6 +481,9 @@ // Enables or disables the Happiness Tracking System for the device. const base::Feature kHappinessTrackingSystem{"HappinessTrackingSystem", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables or disables the Happiness Tracking System for Onboarding Experience. +const base::Feature kHappinessTrackingSystemOnboarding{ + "HappinessTrackingOnboardingExperience", base::FEATURE_DISABLED_BY_DEFAULT}; #endif // Hides the origin text from showing up briefly in WebApp windows.
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 91ad82ef..08673c99 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -320,6 +320,9 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kHappinessTrackingSystem; + +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::Feature kHappinessTrackingSystemOnboarding; #endif COMPONENT_EXPORT(CHROME_FEATURES)
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index b863f320..e163aef 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json
@@ -834,6 +834,9 @@ "tabs.insertCSS": { "max_manifest_version": 2 }, + "tabs.removeCSS": { + "max_manifest_version": 2 + }, "tabs.onActiveChanged": { "max_manifest_version": 2 },
diff --git a/chrome/common/extensions/api/language_settings_private.idl b/chrome/common/extensions/api/language_settings_private.idl index 38c71af..340ff1b2 100644 --- a/chrome/common/extensions/api/language_settings_private.idl +++ b/chrome/common/extensions/api/language_settings_private.idl
@@ -133,6 +133,9 @@ static void getTranslateTargetLanguage( GetTranslateTargetLanguageCallback callback); + // Sets the translate target language given a language code. + static void setTranslateTargetLanguage(DOMString languageCode); + // Gets all supported input methods, including third-party IMEs. // Chrome OS only. static void getInputMethodLists(GetInputMethodListsCallback callback);
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 71060425..906dd41 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -760,13 +760,23 @@ const char kHatsLastInteractionTimestamp[] = "hats_last_interaction_timestamp"; // An int64 pref. This is the timestamp that indicates the end of the most -// recent survey cycle. +// recent survey cycle (general survey). const char kHatsSurveyCycleEndTimestamp[] = "hats_survey_cycle_end_timestamp"; // A boolean pref. Indicates if the device is selected for HaTS in the current -// survey cycle. +// survey cycle (general survey). const char kHatsDeviceIsSelected[] = "hats_device_is_selected"; +// An int64 pref. This is the timestamp that indicates the end of the Onboarding +// Experience survey +const char kHatsOnboardingSurveyCycleEndTs[] = + "hats_onboarding_cycle_end_timestamp"; + +// A boolean pref. Indicates if the device is selected for the HaTS Onboarding +// Experience survey +const char kHatsOnboardingDeviceIsSelected[] = + "hats_onboarding_device_is_selected"; + // A boolean pref. Indicates if we've already shown a notification to inform the // current user about the quick unlock feature. const char kPinUnlockFeatureNotificationShown[] = @@ -1120,6 +1130,9 @@ const char kCurrentThemePackFilename[] = "extensions.theme.pack"; const char kCurrentThemeID[] = "extensions.theme.id"; const char kAutogeneratedThemeColor[] = "autogenerated.theme.color"; +// Policy-controlled SkColor used to generate the browser's theme. The value +// SK_ColorTRANSPARENT means the policy has not been set. +const char kPolicyThemeColor[] = "autogenerated.theme.policy.color"; // Boolean pref which persists whether the extensions_ui is in developer mode // (showing developer packing tools and extensions details)
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index e48a44b..db49fff 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -288,6 +288,8 @@ extern const char kHatsLastInteractionTimestamp[]; extern const char kHatsSurveyCycleEndTimestamp[]; extern const char kHatsDeviceIsSelected[]; +extern const char kHatsOnboardingSurveyCycleEndTs[]; +extern const char kHatsOnboardingDeviceIsSelected[]; extern const char kQuickUnlockPinSecret[]; extern const char kQuickUnlockFingerprintRecord[]; extern const char kEolStatus[]; @@ -372,6 +374,7 @@ extern const char kCurrentThemePackFilename[]; extern const char kCurrentThemeID[]; extern const char kAutogeneratedThemeColor[]; +extern const char kPolicyThemeColor[]; extern const char kExtensionsUIDeveloperMode[]; extern const char kExtensionsUIDismissedADTPromo[]; extern const char kExtensionCommands[];
diff --git a/chrome/install_static/install_util.cc b/chrome/install_static/install_util.cc index 0bada72c..5ed43e2c 100644 --- a/chrome/install_static/install_util.cc +++ b/chrome/install_static/install_util.cc
@@ -688,12 +688,13 @@ GetValueFromVersionResource(data.get(), L"SpecialBuild", special_build); } } - *channel_name = GetChromeChannelName(); + *channel_name = GetChromeChannelName(/*with_extended_stable=*/true); } version_info::Channel GetChromeChannel() { #if BUILDFLAG(GOOGLE_CHROME_BRANDING) - std::wstring channel_name(GetChromeChannelName()); + std::wstring channel_name( + GetChromeChannelName(/*with_extended_stable=*/false)); if (channel_name.empty()) { return version_info::Channel::STABLE; } @@ -711,7 +712,9 @@ return version_info::Channel::UNKNOWN; } -std::wstring GetChromeChannelName() { +std::wstring GetChromeChannelName(bool with_extended_stable) { + if (with_extended_stable && IsExtendedStableChannel()) + return L"extended"; return InstallDetails::Get().channel(); }
diff --git a/chrome/install_static/install_util.h b/chrome/install_static/install_util.h index 6a97107d..3150ec3d 100644 --- a/chrome/install_static/install_util.h +++ b/chrome/install_static/install_util.h
@@ -230,20 +230,22 @@ bool HasEnvironmentVariable(const std::wstring& variable_name); // Gets the exe version details like the |product_name|, |version|, -// |special_build|, |channel_name|, etc. Most of this information is read -// from the version resource. |exe_path| is the path of chrome.exe. -// TODO(ananta) -// http://crbug.com/604923 -// Unify this with the Browser Distribution code. +// |special_build|, and |channel_name| from the browser executable at +// |exe_path|. |channel_name| will be "extended" for clients that follow the +// extended stable update channel. void GetExecutableVersionDetails(const std::wstring& exe_path, std::wstring* product_name, std::wstring* version, std::wstring* special_build, std::wstring* channel_name); -// Gets the channel or channel name for the current Chrome process. +// Gets the channel for the current Chrome process. version_info::Channel GetChromeChannel(); -std::wstring GetChromeChannelName(); + +// Gets the channel for the current Chrome process. Unless +// `with_extended_stable` is true, extended stable will be reported as regular +// stable (i.e., an empty string). +std::wstring GetChromeChannelName(bool with_extended_stable); // Returns true if the current Chrome process is on the extended stable channel. bool IsExtendedStableChannel();
diff --git a/chrome/install_static/install_util_unittest.cc b/chrome/install_static/install_util_unittest.cc index fdbe534f..44bf512 100644 --- a/chrome/install_static/install_util_unittest.cc +++ b/chrome/install_static/install_util_unittest.cc
@@ -710,7 +710,8 @@ } TEST_P(InstallStaticUtilTest, GetChromeChannelName) { - EXPECT_EQ(default_channel(), GetChromeChannelName()); + EXPECT_EQ(default_channel(), + GetChromeChannelName(/*with_extended_stable=*/false)); } TEST_P(InstallStaticUtilTest, GetSandboxSidPrefix) {
diff --git a/chrome/installer/setup/BUILD.gn b/chrome/installer/setup/BUILD.gn index 1a56c73..db3796b 100644 --- a/chrome/installer/setup/BUILD.gn +++ b/chrome/installer/setup/BUILD.gn
@@ -109,6 +109,7 @@ "//components/crash/core/app", "//components/crash/core/common", "//components/metrics", + "//components/version_info:channel", "//components/zucchini:zucchini_io", "//components/zucchini:zucchini_lib", "//courgette:courgette_lib",
diff --git a/chrome/installer/setup/DEPS b/chrome/installer/setup/DEPS index 95da9642..745e760 100644 --- a/chrome/installer/setup/DEPS +++ b/chrome/installer/setup/DEPS
@@ -3,6 +3,7 @@ "+chrome/install_static", "+components/base32", "+components/metrics", + "+components/version_info/channel.h", "+components/zucchini", "+courgette", "+third_party/crashpad",
diff --git a/chrome/installer/setup/installer_crash_reporter_client.cc b/chrome/installer/setup/installer_crash_reporter_client.cc index 7b7eb438..4568caaf 100644 --- a/chrome/installer/setup/installer_crash_reporter_client.cc +++ b/chrome/installer/setup/installer_crash_reporter_client.cc
@@ -18,6 +18,7 @@ #include "chrome/install_static/install_util.h" #include "chrome/installer/setup/installer_crash_reporting.h" #include "chrome/installer/util/google_update_settings.h" +#include "components/version_info/channel.h" InstallerCrashReporterClient::InstallerCrashReporterClient( bool is_per_user_install) @@ -54,7 +55,8 @@ *version = L"0.0.0.0-devel"; } - *channel_name = install_static::GetChromeChannelName(); + *channel_name = + install_static::GetChromeChannelName(/*with_extended_stable=*/true); } bool InstallerCrashReporterClient::ShouldShowRestartDialog( @@ -76,7 +78,7 @@ bool InstallerCrashReporterClient::GetShouldDumpLargerDumps() { // Use large dumps for all but the stable channel. - return !install_static::GetChromeChannelName().empty(); + return install_static::GetChromeChannel() != version_info::Channel::STABLE; } int InstallerCrashReporterClient::GetResultCodeRespawnFailed() {
diff --git a/chrome/notification_helper/notification_helper_crash_reporter_client.cc b/chrome/notification_helper/notification_helper_crash_reporter_client.cc index e9963d218..5bd3290 100644 --- a/chrome/notification_helper/notification_helper_crash_reporter_client.cc +++ b/chrome/notification_helper/notification_helper_crash_reporter_client.cc
@@ -77,7 +77,8 @@ *special_build = std::wstring(); } - *channel_name = install_static::GetChromeChannelName(); + *channel_name = + install_static::GetChromeChannelName(/*with_extended_stable=*/true); } bool NotificationHelperCrashReporterClient::ShouldShowRestartDialog(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index fbe6452..1eb47c6 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4640,6 +4640,7 @@ "../browser/task_manager/test_task_manager.cc", "../browser/task_manager/test_task_manager.h", "../browser/themes/browser_theme_pack_unittest.cc", + "../browser/themes/theme_color_policy_handler_unittest.cc", "../browser/themes/theme_properties_unittest.cc", "../browser/themes/theme_service_unittest.cc", "../browser/themes/theme_syncable_service_unittest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/FieldTrials.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/FieldTrials.java index 863140c..e6042c1 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/FieldTrials.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/FieldTrials.java
@@ -6,6 +6,7 @@ import org.chromium.base.BaseSwitches; import org.chromium.base.CommandLine; +import org.chromium.chrome.browser.flags.AllCachedFieldTrialParameters; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.CachedFieldTrialParameter; @@ -139,6 +140,7 @@ CachedFieldTrialParameter.setForTesting( featureName, param.getKey(), param.getValue()); } + AllCachedFieldTrialParameters.setForTesting(featureName, params); } } } catch (Exception e) {
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 2ebbb77..9b4aac2 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -8544,5 +8544,22 @@ } } ] + }, + "BrowserThemeColor": { + "os": ["win", "linux", "mac"], + "can_be_recommended": false, + "policy_pref_mapping_tests": [ + { + "policies": { + "BrowserThemeColor": "#000000" + }, + "prefs": { + "autogenerated.theme.policy.color": { + "value": -16777216, + "location": "user_profile" + } + } + } + ] } }
diff --git a/chrome/test/data/webui/cr_components/customize_themes_test.js b/chrome/test/data/webui/cr_components/customize_themes_test.js index 6d79b5d..e157243 100644 --- a/chrome/test/data/webui/cr_components/customize_themes_test.js +++ b/chrome/test/data/webui/cr_components/customize_themes_test.js
@@ -10,7 +10,7 @@ import {ChromeTheme, CustomizeThemesClientCallbackRouter, CustomizeThemesHandlerInterface, ThemeType} from 'chrome://resources/cr_components/customize_themes/customize_themes.mojom-webui.js'; import {ThemeIconElement} from 'chrome://resources/cr_components/customize_themes/theme_icon.js'; -import {assertDeepEquals, assertEquals, assertTrue} from '../chai_assert.js'; +import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from '../chai_assert.js'; import {TestBrowserProxy} from '../test_browser_proxy.m.js'; import {flushTasks} from '../test_util.m.js'; @@ -276,7 +276,8 @@ activeTab: {value: 0xff0000ff}, activeTabText: {value: 0xff00ff00}, }, - } + }, + isForced: false, }; await flushTasks(); @@ -311,6 +312,7 @@ customizeThemesElement.selectedTheme = { type: ThemeType.kDefault, info: {chromeThemeId: 0}, + isForced: false, }; await flushTasks(); @@ -352,6 +354,7 @@ customizeThemesElement.selectedTheme = { type: ThemeType.kChrome, info: {chromeThemeId: 0}, + isForced: false, }; await flushTasks(); @@ -374,6 +377,61 @@ assertSingleThemeIconIsFocusableWithTabKey(customizeThemesElement); }); + test('setting policy theme', async () => { + // Arrange. + const customizeThemesElement = createCustomizeThemesElement(); + + // Act. + customizeThemesElement.selectedTheme = { + type: ThemeType.kAutogenerated, + info: { + autogeneratedThemeColors: { + frame: {value: 0xff0000ff}, + activeTab: {value: 0xff00ff00}, + activeTabText: {value: 0xffff0000}, + }, + }, + isForced: true, + }; + await flushTasks(); + + // Assert. + // Theme icon is selected and updated, and color picker icon is hidden. + const selectedIcons = customizeThemesElement.shadowRoot.querySelectorAll( + 'cr-theme-icon[selected]'); + assertEquals(selectedIcons.length, 1); + assertEquals( + selectedIcons[0], + customizeThemesElement.shadowRoot.querySelector('#autogeneratedTheme')); + assertStyle( + selectedIcons[0], '--cr-theme-icon-frame-color', 'rgba(0, 0, 255, 1)'); + assertStyle( + selectedIcons[0], '--cr-theme-icon-active-tab-color', + 'rgba(0, 255, 0, 1)'); + assertDeepEquals( + selectedIcons, + customizeThemesElement.shadowRoot.querySelectorAll( + 'div[aria-checked="true"] cr-theme-icon')); + assertDeepEquals( + selectedIcons, + customizeThemesElement.shadowRoot.querySelectorAll( + 'div[tabindex="0"] cr-theme-icon')); + assertSingleThemeIconIsFocusableWithTabKey(customizeThemesElement); + assertTrue( + customizeThemesElement.shadowRoot.querySelector('#colorPickerIcon') + .hidden); + + // Managed dialog appears on theme click when policy theme is applied. + assertEquals( + null, + customizeThemesElement.shadowRoot.querySelector('managed-dialog')); + customizeThemesElement.shadowRoot.querySelector('#defaultTheme').click(); + await flushTasks(); // Allow managed-dialog to be added to DOM. + assertFalse( + customizeThemesElement.shadowRoot.querySelector('managed-dialog') + .hidden); + }); + test('setting third-party theme shows uninstall UI', async () => { // Arrange. const customizeThemesElement = createCustomizeThemesElement(); @@ -387,6 +445,7 @@ name: 'bar', }, }, + isForced: false, }; // Assert. @@ -411,6 +470,7 @@ name: 'bar', }, }, + isForced: false, }; // Act. @@ -429,6 +489,7 @@ customizeThemesElement.selectedTheme = { type: ThemeType.kDefault, info: {chromeThemeId: 0}, + isForced: false, }; // Assert. @@ -449,6 +510,7 @@ name: 'bar', }, }, + isForced: false, }; // Act. customizeThemesElement.shadowRoot
diff --git a/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.js b/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.js index f369abbf3..dd2a6a2 100644 --- a/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.js +++ b/chrome/test/data/webui/cr_elements/find_shortcut_behavior_test.js
@@ -5,7 +5,7 @@ // clang-format off import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; -import {FindShortcutBehavior, FindShortcutManager} from 'chrome://resources/cr_elements/find_shortcut_behavior.m.js'; +import {FindShortcutBehavior, FindShortcutManager} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {isMac} from 'chrome://resources/js/cr.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
diff --git a/chrome/test/data/webui/settings/fake_language_settings_private.js b/chrome/test/data/webui/settings/fake_language_settings_private.js index f9fc68b5..d16e7646 100644 --- a/chrome/test/data/webui/settings/fake_language_settings_private.js +++ b/chrome/test/data/webui/settings/fake_language_settings_private.js
@@ -349,6 +349,23 @@ } /** + * Gets the translate target language (in most cases, the display locale). + * @param {function(string):void} callback + */ + getTranslateTargetLanguage(callback) { + callback('en'); + } + + /** + * Sets the translate target language. + * @param {string} languageCode + */ + setTranslateTargetLanguage(languageCode) { + this.settingsPrefs_.push( + 'prefs.translate_recent_target.value', languageCode); + } + + /** * Gets the current status of the chosen spell check dictionaries. * @param {function(!Array< * !chrome.languageSettingsPrivate.SpellcheckDictionaryStatus>):void} @@ -386,14 +403,6 @@ } /** - * Gets the translate target language (in most cases, the display locale). - * @param {function(string):void} callback - */ - getTranslateTargetLanguage(callback) { - setTimeout(callback.bind(null, 'en')); - } - - /** * Gets all supported input methods, including third-party IMEs. Chrome OS * only. * @param {function(!chrome.languageSettingsPrivate.InputMethodLists):void} @@ -515,6 +524,11 @@ key: 'translate_blocked_languages', type: chrome.settingsPrivate.PrefType.LIST, value: ['en-US'], + }, + { + key: 'translate_recent_target', + type: chrome.settingsPrivate.PrefType.STRING, + value: 'en-US', } ]; if (isChromeOS) {
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index 64219c8..66e2dc0 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -32,6 +32,7 @@ deps = [ ":updater", ":updater_tests", + ":updater_tests_system", "//chrome/updater/test/test_app", ] } @@ -348,9 +349,7 @@ "tag_unittest.cc", "test/integration_test_commands.h", "test/integration_test_commands_system.cc", - "test/integration_test_commands_system.h", "test/integration_test_commands_user.cc", - "test/integration_test_commands_user.h", "test/integration_tests.cc", "test/integration_tests_impl.cc", "test/integration_tests_impl.h", @@ -432,7 +431,33 @@ test("updater_tests") { testonly = true - sources = [ "run_all_unittests.cc" ] + sources = [ + "run_all_unittests.cc", + "test/integration_test_commands_factory_user.cc", + ] + + deps = [ + ":updater_test_sources", + "//base/test:test_support", + "//chrome/common:constants", + "//testing/gtest", + ] + + if (is_mac) { + data_deps = [ + "//chrome/updater/mac:updater_bundle", + "//chrome/updater/test/test_app", + ] + } + } + + test("updater_tests_system") { + testonly = true + + sources = [ + "run_all_unittests.cc", + "test/integration_test_commands_factory_system.cc", + ] deps = [ ":updater_test_sources", @@ -454,7 +479,10 @@ executable("updater_integration_tests_helper") { testonly = true - sources = [ "test/integration_tests_helper.cc" ] + sources = [ + "test/integration_test_commands_factory_system.cc", + "test/integration_tests_helper.cc", + ] deps = [ ":base",
diff --git a/chrome/updater/tag.cc b/chrome/updater/tag.cc index 0a0d5940..25aca505 100644 --- a/chrome/updater/tag.cc +++ b/chrome/updater/tag.cc
@@ -109,7 +109,7 @@ } // A custom comparator functor class for the parse tables. -using ParseTableCompare = CaseInsensitiveASCIICompare<std::string>; +using ParseTableCompare = CaseInsensitiveASCIICompare; namespace global_attributes {
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h index 1b46610..e52858c 100644 --- a/chrome/updater/test/integration_test_commands.h +++ b/chrome/updater/test/integration_test_commands.h
@@ -47,6 +47,11 @@ virtual ~IntegrationTestCommands() = default; }; +scoped_refptr<IntegrationTestCommands> CreateIntegrationTestCommands(); + +scoped_refptr<IntegrationTestCommands> CreateIntegrationTestCommandsUser(); + +scoped_refptr<IntegrationTestCommands> CreateIntegrationTestCommandsSystem(); } // namespace test } // namespace updater
diff --git a/chrome/updater/test/integration_test_commands_user.h b/chrome/updater/test/integration_test_commands_factory_system.cc similarity index 66% copy from chrome/updater/test/integration_test_commands_user.h copy to chrome/updater/test/integration_test_commands_factory_system.cc index 9b2116d..085e4124 100644 --- a/chrome/updater/test/integration_test_commands_user.h +++ b/chrome/updater/test/integration_test_commands_factory_system.cc
@@ -2,18 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_USER_H_ -#define CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_USER_H_ - #include "base/memory/scoped_refptr.h" #include "chrome/updater/test/integration_test_commands.h" namespace updater { namespace test { -scoped_refptr<IntegrationTestCommands> CreateIntegrationTestCommandsUser(); +scoped_refptr<IntegrationTestCommands> CreateIntegrationTestCommands() { + return CreateIntegrationTestCommandsSystem(); +} } // namespace test } // namespace updater - -#endif // CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_USER_H_
diff --git a/chrome/updater/test/integration_test_commands_user.h b/chrome/updater/test/integration_test_commands_factory_user.cc similarity index 66% rename from chrome/updater/test/integration_test_commands_user.h rename to chrome/updater/test/integration_test_commands_factory_user.cc index 9b2116d..7c0cc84 100644 --- a/chrome/updater/test/integration_test_commands_user.h +++ b/chrome/updater/test/integration_test_commands_factory_user.cc
@@ -2,18 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_USER_H_ -#define CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_USER_H_ - #include "base/memory/scoped_refptr.h" #include "chrome/updater/test/integration_test_commands.h" namespace updater { namespace test { -scoped_refptr<IntegrationTestCommands> CreateIntegrationTestCommandsUser(); +scoped_refptr<IntegrationTestCommands> CreateIntegrationTestCommands() { + return CreateIntegrationTestCommandsUser(); +} } // namespace test } // namespace updater - -#endif // CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_USER_H_
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc index 6348dd4..b005019 100644 --- a/chrome/updater/test/integration_test_commands_system.cc +++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/updater/test/integration_test_commands_system.h" - #include <cstdlib> #include <memory> #include <string> @@ -19,6 +17,7 @@ #include "chrome/updater/constants.h" #include "chrome/updater/persisted_data.h" #include "chrome/updater/prefs.h" +#include "chrome/updater/test/integration_test_commands.h" #include "chrome/updater/test/integration_tests_impl.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/util.h"
diff --git a/chrome/updater/test/integration_test_commands_system.h b/chrome/updater/test/integration_test_commands_system.h deleted file mode 100644 index 097e454..0000000 --- a/chrome/updater/test/integration_test_commands_system.h +++ /dev/null
@@ -1,19 +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. - -#ifndef CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_SYSTEM_H_ -#define CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_SYSTEM_H_ - -#include "base/memory/scoped_refptr.h" -#include "chrome/updater/test/integration_test_commands.h" - -namespace updater { -namespace test { - -scoped_refptr<IntegrationTestCommands> CreateIntegrationTestCommandsSystem(); - -} // namespace test -} // namespace updater - -#endif // CHROME_UPDATER_TEST_INTEGRATION_TEST_COMMANDS_SYSTEM_H_
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc index 79473fc8..87a4138 100644 --- a/chrome/updater/test/integration_test_commands_user.cc +++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/updater/test/integration_test_commands_user.h" - #include <cstdlib> #include <memory> #include <string> @@ -12,6 +10,7 @@ #include "base/files/file_util.h" #include "base/memory/scoped_refptr.h" #include "base/optional.h" +#include "chrome/updater/test/integration_test_commands.h" #include "chrome/updater/test/integration_tests_impl.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/util.h"
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index 26978e5..c0645600 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - #include <cstdlib> #include <memory> @@ -27,8 +26,6 @@ #include "chrome/updater/prefs.h" #include "chrome/updater/registration_data.h" #include "chrome/updater/test/integration_test_commands.h" -#include "chrome/updater/test/integration_test_commands_system.h" -#include "chrome/updater/test/integration_test_commands_user.h" #include "chrome/updater/test/integration_tests_impl.h" #include "chrome/updater/test/server.h" #include "chrome/updater/test/test_app/constants.h" @@ -47,11 +44,18 @@ namespace updater { namespace test { -class IntegrationTest - : public ::testing::TestWithParam<scoped_refptr<IntegrationTestCommands>> { +// TODO(crbug.com/1096654): Enable tests for IntegrationTestCommandsSystem on +// bots that support passwordless sudo. + +// TODO(crbug.com/1096654): Enable for system integration tests for Win. + +class IntegrationTest : public ::testing::Test { + public: + IntegrationTest() : test_commands_(CreateIntegrationTestCommands()) {} + ~IntegrationTest() override = default; + protected: void SetUp() override { - test_commands_ = GetParam(); Clean(); ExpectClean(); EnterTestMode(GURL("http://localhost:1234")); @@ -66,50 +70,71 @@ ExpectClean(); Clean(); } - scoped_refptr<IntegrationTestCommands> test_commands_; void CopyLog() { test_commands_->CopyLog(); } + void PrintLog() { test_commands_->PrintLog(); } + void Install() { test_commands_->Install(); } + void ExpectInstalled() { test_commands_->ExpectInstalled(); } + void Uninstall() { test_commands_->Uninstall(); } + void ExpectCandidateUninstalled() { test_commands_->ExpectCandidateUninstalled(); } + void Clean() { test_commands_->Clean(); } + void ExpectClean() { test_commands_->ExpectClean(); } + void EnterTestMode(const GURL& url) { test_commands_->EnterTestMode(url); } + void ExpectVersionActive(const std::string& version) { test_commands_->ExpectVersionActive(version); } + void ExpectVersionNotActive(const std::string& version) { test_commands_->ExpectVersionNotActive(version); } + void ExpectActiveUpdater() { test_commands_->ExpectActiveUpdater(); } + void SetupFakeUpdaterHigherVersion() { test_commands_->SetupFakeUpdaterHigherVersion(); } + void SetActive(const std::string& app_id) { test_commands_->SetActive(app_id); } + void ExpectActive(const std::string& app_id) { test_commands_->ExpectActive(app_id); } + void ExpectNotActive(const std::string& app_id) { test_commands_->ExpectNotActive(app_id); } + void SetFakeExistenceCheckerPath(const std::string& app_id) { test_commands_->SetFakeExistenceCheckerPath(app_id); } + void ExpectAppUnregisteredExistenceCheckerPath(const std::string& app_id) { test_commands_->ExpectAppUnregisteredExistenceCheckerPath(app_id); } + void RegisterApp(const std::string& app_id) { test_commands_->RegisterApp(app_id); } + void RegisterTestApp() { test_commands_->RegisterTestApp(); } + void RunWake(int exit_code) { test_commands_->RunWake(exit_code); } + scoped_refptr<IntegrationTestCommands> test_commands_; + private: base::test::TaskEnvironment environment_; }; @@ -120,7 +145,7 @@ // See crbug.com/1112527. #if defined(OS_WIN) || !defined(COMPONENT_BUILD) -TEST_P(IntegrationTest, InstallUninstall) { +TEST_F(IntegrationTest, InstallUninstall) { Install(); ExpectInstalled(); ExpectVersionActive(UPDATER_VERSION_STRING); @@ -134,7 +159,7 @@ Uninstall(); } -TEST_P(IntegrationTest, SelfUninstallOutdatedUpdater) { +TEST_F(IntegrationTest, SelfUninstallOutdatedUpdater) { Install(); ExpectInstalled(); SetupFakeUpdaterHigherVersion(); @@ -159,7 +184,7 @@ #if defined(OS_MAC) // TODO(crbug.com/1163524): Enable on Windows. -TEST_P(IntegrationTest, RegisterTestApp) { +TEST_F(IntegrationTest, RegisterTestApp) { RegisterTestApp(); ExpectInstalled(); ExpectVersionActive(UPDATER_VERSION_STRING); @@ -169,7 +194,7 @@ #endif // OS_MAC // TODO(crbug.com/1163625): Failing on Mac 10.11. -TEST_P(IntegrationTest, ReportsActive) { +TEST_F(IntegrationTest, ReportsActive) { // A longer than usual timeout is needed for this test because the macOS // UpdateServiceInternal server takes at least 10 seconds to shut down after // Install, and RegisterApp cannot make progress until it shut downs and @@ -214,7 +239,7 @@ #else #define MAYBE_UnregisterUninstalledApp UnregisterUninstalledApp #endif -TEST_P(IntegrationTest, MAYBE_UnregisterUninstalledApp) { +TEST_F(IntegrationTest, MAYBE_UnregisterUninstalledApp) { RegisterTestApp(); ExpectInstalled(); ExpectVersionActive(UPDATER_VERSION_STRING); @@ -243,7 +268,7 @@ #define MAYBE_UninstallUpdaterWhenAllAppsUninstalled \ UninstallUpdaterWhenAllAppsUninstalled #endif -TEST_P(IntegrationTest, MAYBE_UninstallUpdaterWhenAllAppsUninstalled) { +TEST_F(IntegrationTest, MAYBE_UninstallUpdaterWhenAllAppsUninstalled) { RegisterTestApp(); ExpectInstalled(); ExpectVersionActive(UPDATER_VERSION_STRING); @@ -263,7 +288,7 @@ #else #define MAYBE_UnregisterUnownedApp UnregisterUnownedApp #endif -TEST_P(IntegrationTest, MAYBE_UnregisterUnownedApp) { +TEST_F(IntegrationTest, MAYBE_UnregisterUnownedApp) { RegisterTestApp(); ExpectInstalled(); ExpectVersionActive(UPDATER_VERSION_STRING); @@ -297,21 +322,6 @@ #endif // OS_MAC -#if defined(OS_MAC) -// TODO(crbug.com/1096654): Enable tests for IntegrationTestCommandsSystem on -// bots that support passwordless sudo. -INSTANTIATE_TEST_SUITE_P(IntegrationTestVariations, - IntegrationTest, - testing::Values(CreateIntegrationTestCommandsUser())); -#endif - -#if defined(OS_WIN) -// TODO(crbug.com/1096654): Enable for system. -INSTANTIATE_TEST_SUITE_P(IntegrationTestVariations, - IntegrationTest, - testing::Values(CreateIntegrationTestCommandsUser())); -#endif - #endif // defined(OS_WIN) || !defined(COMPONENT_BUILD) } // namespace test
diff --git a/chrome/updater/util.h b/chrome/updater/util.h index 619f2b8..2d0cc2f 100644 --- a/chrome/updater/util.h +++ b/chrome/updater/util.h
@@ -51,12 +51,11 @@ base::CommandLine MakeElevated(base::CommandLine command_line); // Functor used by associative containers of strings as a case-insensitive ASCII -// compare. |T| could be std::string or std::u16string. -template <typename T> +// compare. |StringT| could be either UTF-8 or UTF-16. struct CaseInsensitiveASCIICompare { public: - bool operator()(base::BasicStringPiece<T> x, - base::BasicStringPiece<T> y) const { + template <typename StringT> + bool operator()(const StringT& x, const StringT& y) const { return base::CompareCaseInsensitiveASCII(x, y) > 0; } };
diff --git a/chrome/updater/win/setup/setup_util.cc b/chrome/updater/win/setup/setup_util.cc index 0ceb0bb..dbe6ed7d 100644 --- a/chrome/updater/win/setup/setup_util.cc +++ b/chrome/updater/win/setup/setup_util.cc
@@ -262,8 +262,7 @@ std::string contents; if (!base::ReadFileToStringWithMaxSize(deps, &contents, kDepsFileSizeMax)) return {}; - const base::flat_set<const wchar_t*, - CaseInsensitiveASCIICompare<std::wstring>> + const base::flat_set<const wchar_t*, CaseInsensitiveASCIICompare> exclude_extensions = {L".pdb", L".js"}; std::vector<base::FilePath> result; for (const auto& line :
diff --git a/chromecast/browser/accessibility/flutter/flutter_accessibility_helper_bridge.cc b/chromecast/browser/accessibility/flutter/flutter_accessibility_helper_bridge.cc index 479e3d62..4ef0135 100644 --- a/chromecast/browser/accessibility/flutter/flutter_accessibility_helper_bridge.cc +++ b/chromecast/browser/accessibility/flutter/flutter_accessibility_helper_bridge.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "base/task/post_task.h" #include "chromecast/browser/accessibility/accessibility_manager.h" #include "chromecast/browser/accessibility/proto/gallium_server_accessibility.grpc.pb.h" #include "chromecast/browser/cast_browser_process.h" @@ -114,8 +113,8 @@ std::make_unique<::gallium::castos::OnAccessibilityEventRequest>( *event_data); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&FlutterAccessibilityHelperBridge:: + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&FlutterAccessibilityHelperBridge:: OnAccessibilityEventRequestInternal, base::Unretained(this), std::move(event))); return true;
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 1306fa0b..fb4f14b 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -19,7 +19,6 @@ #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "base/unguessable_token.h" #include "build/build_config.h" @@ -279,8 +278,7 @@ base::BindRepeating(&CastContentBrowserClient::GetCmaBackendFactory, base::Unretained(this)), base::BindRepeating(&shell::CastSessionIdMap::GetSessionId), - base::CreateSingleThreadTaskRunner({content::BrowserThread::UI}), - GetMediaTaskRunner(), + content::GetUIThreadTaskRunner({}), GetMediaTaskRunner(), ServiceConnector::MakeRemote(kBrowserProcessClientId), BUILDFLAG(ENABLE_CAST_AUDIO_MANAGER_MIXER)); #elif defined(OS_ANDROID) @@ -304,8 +302,7 @@ base::BindRepeating(&CastContentBrowserClient::GetCmaBackendFactory, base::Unretained(this)), base::BindRepeating(&shell::CastSessionIdMap::GetSessionId), - base::CreateSingleThreadTaskRunner({content::BrowserThread::UI}), - GetMediaTaskRunner(), + content::GetUIThreadTaskRunner({}), GetMediaTaskRunner(), ServiceConnector::MakeRemote(kBrowserProcessClientId), BUILDFLAG(ENABLE_CAST_AUDIO_MANAGER_MIXER)); #endif @@ -635,8 +632,8 @@ std::string session_id = CastNavigationUIData::GetSessionIdForWebContents(web_contents); DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::PostTask( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &CastContentBrowserClient::SelectClientCertificateOnIOThread, base::Unretained(this), requesting_url, session_id,
diff --git a/chromecast/browser/webview/webview_browsertest.cc b/chromecast/browser/webview/webview_browsertest.cc index 6a563a1..98305295 100644 --- a/chromecast/browser/webview/webview_browsertest.cc +++ b/chromecast/browser/webview/webview_browsertest.cc
@@ -5,7 +5,6 @@ #include "base/bind.h" #include "base/callback.h" #include "base/check_op.h" -#include "base/task/post_task.h" #include "base/test/scoped_run_loop_timeout.h" #include "chromecast/base/chromecast_switches.h" #include "chromecast/browser/cast_browser_process.h" @@ -14,6 +13,7 @@ #include "chromecast/browser/webview/webview_controller.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" @@ -92,8 +92,8 @@ // asynchronously. void SubmitWebviewRequest(WebviewController* controller, const webview::WebviewRequest& request) { - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&WebviewController::ProcessRequest, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&WebviewController::ProcessRequest, base::Unretained(controller), request)); } @@ -101,8 +101,8 @@ void SubmitNavigation(content::WebContents* web_contents, const std::string& path) { GURL url = embedded_test_server()->GetURL("foo.com", path); - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( [](content::WebContents* web_contents, const GURL& url) { ignore_result(content::NavigateToURL(web_contents, url));
diff --git a/chromecast/media/cma/backend/desktop/BUILD.gn b/chromecast/media/cma/backend/desktop/BUILD.gn index 2c1e712..4eaab18e 100644 --- a/chromecast/media/cma/backend/desktop/BUILD.gn +++ b/chromecast/media/cma/backend/desktop/BUILD.gn
@@ -24,14 +24,16 @@ "//chromecast/public/media", "//media", ] - if (enable_video_with_mixed_audio) { + if (enable_video_with_mixed_audio || is_cast_audio_only) { sources += [ "desktop_system_volume_control.cc" ] deps += [ "//chromecast/media/cma/backend:for_mixer_audio", "//chromecast/media/cma/backend:null_video", "//chromecast/media/cma/backend:public", - "//chromecast/media/cma/backend/video:av_sync_video", ] + if (enable_video_with_mixed_audio) { + deps += [ "//chromecast/media/cma/backend/video:av_sync_video" ] + } } else { sources += [ "volume_control_desktop.cc" ] } @@ -39,8 +41,8 @@ cast_source_set("mixer_output") { sources = [ + "mixer_output_stream_desktop.cc", "mixer_output_stream_desktop.h", - "mixer_output_stream_desktop.cc" ] deps = [ "//base", @@ -48,4 +50,3 @@ "//media", ] } -
diff --git a/chromeos/components/phonehub/notification_access_manager_impl.cc b/chromeos/components/phonehub/notification_access_manager_impl.cc index 0120165..f9a277c 100644 --- a/chromeos/components/phonehub/notification_access_manager_impl.cc +++ b/chromeos/components/phonehub/notification_access_manager_impl.cc
@@ -100,10 +100,14 @@ // We're already connecting, so wait until a connection succeeds before // trying to send a message case FeatureStatus::kEnabledAndConnecting: + SetNotificationSetupOperationStatus( + NotificationAccessSetupOperation::Status::kConnecting); break; // We are not connected, so schedule a connection; once the // connection succeeds, we'll send the message in OnFeatureStatusChanged(). case FeatureStatus::kEnabledButDisconnected: + SetNotificationSetupOperationStatus( + NotificationAccessSetupOperation::Status::kConnecting); connection_scheduler_->ScheduleConnectionNow(); break; default:
diff --git a/chromeos/components/phonehub/notification_access_setup_operation.cc b/chromeos/components/phonehub/notification_access_setup_operation.cc index 7c667dca..3b6c07a 100644 --- a/chromeos/components/phonehub/notification_access_setup_operation.cc +++ b/chromeos/components/phonehub/notification_access_setup_operation.cc
@@ -8,6 +8,7 @@ #include "base/check.h" #include "base/containers/contains.h" +#include "base/metrics/histogram_functions.h" namespace chromeos { namespace phonehub { @@ -25,6 +26,13 @@ kProhibitedFromProvidingAccess, }; +// Used for metrics; do not change. +constexpr size_t kNumSetupDurationHistogramBuckets = 50; +constexpr base::TimeDelta kSetupDurationHistogramMinTime = + base::TimeDelta::FromSeconds(1); +constexpr base::TimeDelta kSetupDurationHistogramMaxTime = + base::TimeDelta::FromMinutes(10); + } // namespace // static @@ -42,10 +50,26 @@ } NotificationAccessSetupOperation::~NotificationAccessSetupOperation() { + if (current_status_) { + base::UmaHistogramEnumeration("PhoneHub.NotificationAccessSetup.LastStatus", + *current_status_); + } + std::move(destructor_callback_).Run(); } void NotificationAccessSetupOperation::NotifyStatusChanged(Status new_status) { + base::UmaHistogramEnumeration("PhoneHub.NotificationAccessSetup.AllStatuses", + new_status); + if (new_status == Status::kCompletedSuccessfully) { + base::UmaHistogramCustomTimes( + "PhoneHub.NotificationAccessSetup.SuccessfulSetupDuration", + base::TimeTicks::Now() - start_timestamp_, + kSetupDurationHistogramMinTime, kSetupDurationHistogramMaxTime, + kNumSetupDurationHistogramBuckets); + } + current_status_ = new_status; + delegate_->OnStatusChange(new_status); }
diff --git a/chromeos/components/phonehub/notification_access_setup_operation.h b/chromeos/components/phonehub/notification_access_setup_operation.h index 2b450d4..d8c33809b 100644 --- a/chromeos/components/phonehub/notification_access_setup_operation.h +++ b/chromeos/components/phonehub/notification_access_setup_operation.h
@@ -8,6 +8,8 @@ #include <ostream> #include "base/callback.h" +#include "base/optional.h" +#include "base/time/time.h" namespace chromeos { namespace phonehub { @@ -28,7 +30,9 @@ public: // Note: Numerical values should not be changed because they must stay in // sync with multidevice_notification_access_setup_dialog.js, with the - // exception of NOT_STARTED, which has a value of 0. + // exception of NOT_STARTED, which has a value of 0. Also, these values are + // persisted to logs. Entries should not be renumbered and numeric values + // should never be reused. If entries are added, kMaxValue should be updated. enum class Status { // Connecting to the phone in order to set up notification access. kConnecting = 1, @@ -51,7 +55,9 @@ // The user's phone is prohibited from granting notification access (e.g., // the user could be using a Work Profile). - kProhibitedFromProvidingAccess = 6 + kProhibitedFromProvidingAccess = 6, + + kMaxValue = kProhibitedFromProvidingAccess }; // Returns true if the provided status is the final one for this operation, @@ -80,6 +86,8 @@ void NotifyStatusChanged(Status new_status); + base::Optional<Status> current_status_; + const base::TimeTicks start_timestamp_ = base::TimeTicks::Now(); Delegate* const delegate_; base::OnceClosure destructor_callback_; };
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom index 4d40e05..00a7639 100644 --- a/chromeos/crosapi/mojom/crosapi.mojom +++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -373,8 +373,14 @@ // BrowserService defines the APIs that live in a browser (such as // lacros-chrome) and are accessed from ash-chrome. +// IMPORTANT NOTE: If you are exposing a new capability from Lacros to Ash, +// create a new mojom file. See automation.mojom for an example. This interface +// has accidentally become a kitchen sink for different features. This was not +// intentional. +// // Next MinVersion: 11. // Next ID: 9 +// [Stable, Uuid="4e04dc16-b34c-40fd-9e3f-3c55c2c6cf91", RenamedFrom="crosapi.mojom.LacrosChromeService"] interface BrowserService {
diff --git a/chromeos/services/assistant/public/cpp/features.cc b/chromeos/services/assistant/public/cpp/features.cc index 3acf098..13b2406 100644 --- a/chromeos/services/assistant/public/cpp/features.cc +++ b/chromeos/services/assistant/public/cpp/features.cc
@@ -32,9 +32,6 @@ const base::Feature kAssistantRoutines{"AssistantRoutines", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kAssistantTimersV2{"AssistantTimersV2", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kAssistantWaitScheduling{"AssistantWaitScheduling", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -115,10 +112,6 @@ base::FeatureList::IsEnabled(kAssistantAudioEraser); } -bool IsTimersV2Enabled() { - return base::FeatureList::IsEnabled(kAssistantTimersV2); -} - bool IsVoiceMatchDisabled() { return base::FeatureList::IsEnabled(kDisableVoiceMatch); }
diff --git a/chromeos/services/assistant/public/cpp/features.h b/chromeos/services/assistant/public/cpp/features.h index 8204044..8f7cdec0 100644 --- a/chromeos/services/assistant/public/cpp/features.h +++ b/chromeos/services/assistant/public/cpp/features.h
@@ -36,11 +36,6 @@ COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const base::Feature kAssistantRoutines; -// When enabled, we support the second version of timers UX which includes new -// UI treatments for timers in Assistant and System UI. -COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) -extern const base::Feature kAssistantTimersV2; - // Enables server-driven wait scheduling. This allows the server to inject // pauses into the interaction response to give the user time to digest one leg // of a routine before proceeding to the next, for example, or to provide @@ -108,8 +103,6 @@ COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsStereoAudioInputEnabled(); -COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsTimersV2Enabled(); - COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsVoiceMatchDisabled(); COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsWaitSchedulingEnabled();
diff --git a/chromeos/services/libassistant/timer_controller.cc b/chromeos/services/libassistant/timer_controller.cc index c6a9e28..4b0337f4 100644 --- a/chromeos/services/libassistant/timer_controller.cc +++ b/chromeos/services/libassistant/timer_controller.cc
@@ -48,13 +48,6 @@ if (event.type != assistant_client::AlarmTimerEvent::TIMER) continue; - // We always handle timers that have fired. Only for timers v2, however, do - // we handle scheduled/paused timers so we can represent those states in UI. - if (event.timer_data.state != assistant_client::Timer::State::FIRED && - !assistant::features::IsTimersV2Enabled()) { - continue; - } - AssistantTimer timer; timer.id = event.timer_data.timer_id; timer.label = event.timer_data.label; @@ -113,7 +106,6 @@ weak_ptr)); }); - if (assistant::features::IsTimersV2Enabled()) { // In timers v2, we also want to know when timers are scheduled, // updated, and/or removed so that we can represent those states // in UI. @@ -129,7 +121,6 @@ // Force sync the initial timer state. OnAlarmTimerStateChanged(); - } } void Stop() {
diff --git a/chromeos/services/libassistant/timer_controller_unittest.cc b/chromeos/services/libassistant/timer_controller_unittest.cc index 8d5c747b..1af6bf7 100644 --- a/chromeos/services/libassistant/timer_controller_unittest.cc +++ b/chromeos/services/libassistant/timer_controller_unittest.cc
@@ -118,41 +118,7 @@ TimerController controller_; }; -TEST_F(AssistantTimerControllerTest, - ShouldNotifyDelegateOfOnlyRingingTimersInV1) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - assistant::features::kAssistantTimersV2); - - StartLibassistant(); - - EXPECT_CALL(delegate(), OnTimerStateChanged) - .WillOnce(Invoke([](const auto& timers) { - ASSERT_EQ(1u, timers.size()); - EXPECT_EQ(AssistantTimerState::kFired, timers[0].state); - })); - - std::vector<assistant_client::AlarmTimerEvent> events; - - // Ignore NONE, ALARMs, and SCHEDULED/PAUSED timers. - AddAlarmTimerEvent(&events, assistant_client::AlarmTimerEvent::Type::NONE); - AddAlarmTimerEvent(&events, assistant_client::AlarmTimerEvent::Type::ALARM); - AddTimerEvent(&events, assistant_client::Timer::State::SCHEDULED); - AddTimerEvent(&events, assistant_client::Timer::State::PAUSED); - - // Accept FIRED timers. - AddTimerEvent(&events, assistant_client::Timer::State::FIRED); - - fake_alarm_timer_manager().SetAllEvents(std::move(events)); - fake_alarm_timer_manager().NotifyRingingStateListeners(); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(AssistantTimerControllerTest, ShouldNotifyDelegateOfAnyTimersInV2) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - assistant::features::kAssistantTimersV2); - +TEST_F(AssistantTimerControllerTest, ShouldNotifyDelegateOfAnyTimers) { // We expect OnTimerStateChanged() to be invoked when starting LibAssistant. EXPECT_CALL(delegate(), OnTimerStateChanged).Times(1); @@ -186,11 +152,7 @@ } TEST_F(AssistantTimerControllerTest, - ShouldNotifyDelegateOfTimersWhenStartingLibAssistantInV2) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - assistant::features::kAssistantTimersV2); - + ShouldNotifyDelegateOfTimersWhenStartingLibAssistant) { // Pre-populate the AlarmTimerManager with a single scheduled timer. std::vector<assistant_client::AlarmTimerEvent> events; AddTimerEvent(&events, assistant_client::Timer::State::SCHEDULED);
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 507259b7..ee781e5 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -152,6 +152,8 @@ "form_parsing/field_candidates.h", "form_parsing/form_field.cc", "form_parsing/form_field.h", + "form_parsing/merchant_promo_code_field.cc", + "form_parsing/merchant_promo_code_field.h", "form_parsing/name_field.cc", "form_parsing/name_field.h", "form_parsing/phone_field.cc", @@ -660,6 +662,7 @@ "form_parsing/credit_card_field_unittest.cc", "form_parsing/field_candidates_unittest.cc", "form_parsing/form_field_unittest.cc", + "form_parsing/merchant_promo_code_field_unittest.cc", "form_parsing/name_field_unittest.cc", "form_parsing/parsing_test_utils.cc", "form_parsing/parsing_test_utils.h",
diff --git a/components/autofill/core/browser/autofill_regex_constants.cc b/components/autofill/core/browser/autofill_regex_constants.cc index ae58f14..a97cf21 100644 --- a/components/autofill/core/browser/autofill_regex_constants.cc +++ b/components/autofill/core/browser/autofill_regex_constants.cc
@@ -596,4 +596,10 @@ const char kSocialSecurityRe[] = "ssn|social.?security.?(num(ber)?|#)*"; const char kOneTimePwdRe[] = "one.?time|sms.?(code|token|password|pwd|pass)"; +///////////////////////////////////////////////////////////////////////////// +// merchant_promo_code_field.cc +///////////////////////////////////////////////////////////////////////////// +const char kMerchantPromoCodeRe[] = + "\\bpromo code\\b|\\bcoupon code\\b|\\bgift code\\b"; + } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_regex_constants.h b/components/autofill/core/browser/autofill_regex_constants.h index d755da5..b580d52 100644 --- a/components/autofill/core/browser/autofill_regex_constants.h +++ b/components/autofill/core/browser/autofill_regex_constants.h
@@ -75,6 +75,7 @@ extern const char kCreditCard4DigitExpYearPattern[]; extern const char kSocialSecurityRe[]; extern const char kOneTimePwdRe[]; +extern const char kMerchantPromoCodeRe[]; // Used to match field data that might be a UPI Virtual Payment Address. // See:
diff --git a/components/autofill/core/browser/autofill_type.cc b/components/autofill/core/browser/autofill_type.cc index 83ceb74..9b583bf8 100644 --- a/components/autofill/core/browser/autofill_type.cc +++ b/components/autofill/core/browser/autofill_type.cc
@@ -103,6 +103,11 @@ case COMPANY_NAME: return FieldTypeGroup::kCompany; + case MERCHANT_PROMO_CODE: + // TODO(crbug/1190334): Create new field type group kMerchantPromoCode. + // (This involves updating many switch statements.) + return FieldTypeGroup::kNoGroup; + case PASSWORD: case ACCOUNT_CREATION_PASSWORD: case NOT_ACCOUNT_CREATION_PASSWORD: @@ -125,7 +130,6 @@ case PHONE_FAX_WHOLE_NUMBER: case FIELD_WITH_DEFAULT_VALUE: case MERCHANT_EMAIL_SIGNUP: - case MERCHANT_PROMO_CODE: case UPI_VPA: return FieldTypeGroup::kNoGroup;
diff --git a/components/autofill/core/browser/field_types.cc b/components/autofill/core/browser/field_types.cc index 78e6b52..79283d6 100644 --- a/components/autofill/core/browser/field_types.cc +++ b/components/autofill/core/browser/field_types.cc
@@ -99,6 +99,10 @@ case COMPANY_NAME: return true; + case MERCHANT_PROMO_CODE: + // TODO(crbug/1190334): Create flag for this and use flag value instead. + return false; + // Fillable credential fields. case USERNAME: case PASSWORD: @@ -130,7 +134,6 @@ case PHONE_FAX_WHOLE_NUMBER: case FIELD_WITH_DEFAULT_VALUE: case MERCHANT_EMAIL_SIGNUP: - case MERCHANT_PROMO_CODE: case PRICE: case SEARCH_TERM: case UNKNOWN_TYPE:
diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h index 985aa72a..a0feacc 100644 --- a/components/autofill/core/browser/field_types.h +++ b/components/autofill/core/browser/field_types.h
@@ -106,6 +106,8 @@ // these are likely to be filled out differently on a case by case basis, // they are here primarily for use by Autocheckout. MERCHANT_EMAIL_SIGNUP = 73, + // A promo/gift/coupon code, usually entered during checkout on a commerce web + // site to reduce the cost of a purchase. MERCHANT_PROMO_CODE = 74, // Field types for the password fields. PASSWORD is the default type for all
diff --git a/components/autofill/core/browser/form_parsing/form_field.cc b/components/autofill/core/browser/form_parsing/form_field.cc index 0eb59c0..3a7c38cb 100644 --- a/components/autofill/core/browser/form_parsing/form_field.cc +++ b/components/autofill/core/browser/form_parsing/form_field.cc
@@ -23,6 +23,7 @@ #include "components/autofill/core/browser/form_parsing/autofill_scanner.h" #include "components/autofill/core/browser/form_parsing/credit_card_field.h" #include "components/autofill/core/browser/form_parsing/email_field.h" +#include "components/autofill/core/browser/form_parsing/merchant_promo_code_field.h" #include "components/autofill/core/browser/form_parsing/name_field.h" #include "components/autofill/core/browser/form_parsing/phone_field.h" #include "components/autofill/core/browser/form_parsing/price_field.h" @@ -40,7 +41,7 @@ // There's an implicit precedence determined by the values assigned here. Email // is currently the most important followed by Phone, Travel, Address, -// Credit Card, Name, and Search. +// Credit Card, Price, Name, Merchant promo code, and Search. const float FormField::kBaseEmailParserScore = 1.4f; const float FormField::kBasePhoneParserScore = 1.3f; const float FormField::kBaseTravelParserScore = 1.2f; @@ -48,6 +49,7 @@ const float FormField::kBaseCreditCardParserScore = 1.0f; const float FormField::kBasePriceParserScore = 0.95f; const float FormField::kBaseNameParserScore = 0.9f; +const float FormField::kBaseMerchantPromoCodeParserScore = 0.85f; const float FormField::kBaseSearchParserScore = 0.8f; // static @@ -103,6 +105,10 @@ ParseFormFieldsPass(NameField::Parse, processed_fields, &field_candidates, page_language, log_manager); + // Merchant promo code pass. + ParseFormFieldsPass(MerchantPromoCodeField::Parse, processed_fields, + &field_candidates, page_language, log_manager); + // Search pass. ParseFormFieldsPass(SearchField::Parse, processed_fields, &field_candidates, page_language, log_manager);
diff --git a/components/autofill/core/browser/form_parsing/form_field.h b/components/autofill/core/browser/form_parsing/form_field.h index b9f12294..b883eee 100644 --- a/components/autofill/core/browser/form_parsing/form_field.h +++ b/components/autofill/core/browser/form_parsing/form_field.h
@@ -64,6 +64,7 @@ static const float kBaseCreditCardParserScore; static const float kBasePriceParserScore; static const float kBaseNameParserScore; + static const float kBaseMerchantPromoCodeParserScore; static const float kBaseSearchParserScore; // Only derived classes may instantiate.
diff --git a/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc new file mode 100644 index 0000000..2a147f0 --- /dev/null +++ b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc
@@ -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. + +#include "components/autofill/core/browser/form_parsing/merchant_promo_code_field.h" + +#include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/autofill_field.h" +#include "components/autofill/core/browser/autofill_regex_constants.h" +#include "components/autofill/core/browser/form_parsing/autofill_scanner.h" +#include "components/autofill/core/common/autofill_payments_features.h" + +namespace autofill { + +// static +std::unique_ptr<FormField> MerchantPromoCodeField::Parse( + AutofillScanner* scanner, + const LanguageCode& page_language, + LogManager* log_manager) { + if (!base::FeatureList::IsEnabled( + features::kAutofillParseMerchantPromoCodeFields)) { + return nullptr; + } + + AutofillField* field; + const std::vector<MatchingPattern>& merchant_promo_code_patterns = + PatternProvider::GetInstance().GetMatchPatterns("MERCHANT_PROMO_CODE", + page_language); + + if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kMerchantPromoCodeRe), + MATCH_DEFAULT | MATCH_NUMBER | MATCH_TEXT_AREA, + merchant_promo_code_patterns, &field, + {log_manager, kMerchantPromoCodeRe})) { + return std::make_unique<MerchantPromoCodeField>(field); + } + + return nullptr; +} + +MerchantPromoCodeField::MerchantPromoCodeField(const AutofillField* field) + : field_(field) {} + +void MerchantPromoCodeField::AddClassifications( + FieldCandidatesMap* field_candidates) const { + AddClassification(field_, MERCHANT_PROMO_CODE, + kBaseMerchantPromoCodeParserScore, field_candidates); +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/form_parsing/merchant_promo_code_field.h b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.h new file mode 100644 index 0000000..02369ac9 --- /dev/null +++ b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.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 COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_MERCHANT_PROMO_CODE_FIELD_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_MERCHANT_PROMO_CODE_FIELD_H_ + +#include <memory> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "components/autofill/core/browser/form_parsing/form_field.h" +#include "components/autofill/core/browser/pattern_provider/pattern_provider.h" +#include "components/autofill/core/common/language_code.h" + +namespace autofill { + +class AutofillField; +class AutofillScanner; +class LogManager; + +// A form field that accepts promo/gift/coupon codes during checkout on a +// merchant's web site. +class MerchantPromoCodeField : public FormField { + public: + static std::unique_ptr<FormField> Parse(AutofillScanner* scanner, + const LanguageCode& page_language, + LogManager* log_manager); + explicit MerchantPromoCodeField(const AutofillField* field); + + MerchantPromoCodeField(const MerchantPromoCodeField&) = delete; + MerchantPromoCodeField& operator=(const MerchantPromoCodeField&) = delete; + + protected: + void AddClassifications(FieldCandidatesMap* field_candidates) const override; + + private: + FRIEND_TEST_ALL_PREFIXES(MerchantPromoCodeFieldTest, ParsePromoCode); + FRIEND_TEST_ALL_PREFIXES(MerchantPromoCodeFieldTest, ParseCouponCode); + FRIEND_TEST_ALL_PREFIXES(MerchantPromoCodeFieldTest, ParseGiftCode); + FRIEND_TEST_ALL_PREFIXES(MerchantPromoCodeFieldTest, ParseNonPromoCode); + FRIEND_TEST_ALL_PREFIXES(MerchantPromoCodeFieldTest, ParsePromoCodeFlagOff); + + const AutofillField* field_; +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_MERCHANT_PROMO_CODE_FIELD_H_
diff --git a/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc b/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc new file mode 100644 index 0000000..fc90673 --- /dev/null +++ b/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc
@@ -0,0 +1,81 @@ +// 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 "components/autofill/core/browser/form_parsing/merchant_promo_code_field.h" + +#include "base/test/scoped_feature_list.h" +#include "components/autofill/core/browser/form_parsing/parsing_test_utils.h" +#include "components/autofill/core/common/autofill_payments_features.h" + +using base::ASCIIToUTF16; + +namespace autofill { + +class MerchantPromoCodeFieldTest : public FormFieldTest { + public: + MerchantPromoCodeFieldTest() = default; + MerchantPromoCodeFieldTest(const MerchantPromoCodeFieldTest&) = delete; + MerchantPromoCodeFieldTest& operator=(const MerchantPromoCodeFieldTest&) = + delete; + + protected: + std::unique_ptr<FormField> Parse( + AutofillScanner* scanner, + const LanguageCode& page_language = LanguageCode("en")) override { + return MerchantPromoCodeField::Parse(scanner, page_language, nullptr); + } +}; + +TEST_F(MerchantPromoCodeFieldTest, ParsePromoCode) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kAutofillParseMerchantPromoCodeFields); + AddTextFormFieldData("Enter promo code here", "promoCodeField", + MERCHANT_PROMO_CODE); + + ClassifyAndVerify(ParseResult::PARSED); +} + +TEST_F(MerchantPromoCodeFieldTest, ParseCouponCode) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kAutofillParseMerchantPromoCodeFields); + AddTextFormFieldData("Enter coupon code", "couponCodeField", + MERCHANT_PROMO_CODE); + + ClassifyAndVerify(ParseResult::PARSED); +} + +TEST_F(MerchantPromoCodeFieldTest, ParseGiftCode) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kAutofillParseMerchantPromoCodeFields); + AddTextFormFieldData("Check out with gift code", "giftCodeField", + MERCHANT_PROMO_CODE); + + ClassifyAndVerify(ParseResult::PARSED); +} + +TEST_F(MerchantPromoCodeFieldTest, ParseNonPromoCode) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kAutofillParseMerchantPromoCodeFields); + // Regex relies on "promo/coupon/gift" + "code" together. + AddTextFormFieldData("Field for gift card or promo details", "otherField", + UNKNOWN_TYPE); + + ClassifyAndVerify(ParseResult::NOT_PARSED); +} + +TEST_F(MerchantPromoCodeFieldTest, ParsePromoCodeFlagOff) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature( + features::kAutofillParseMerchantPromoCodeFields); + AddTextFormFieldData("Enter promo code here", "promoCodeField", + MERCHANT_PROMO_CODE); + + ClassifyAndVerify(ParseResult::NOT_PARSED); +} + +} // namespace autofill
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 2cf38a79..607a3a13 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -92,6 +92,11 @@ const base::Feature kAutofillEnableVirtualCard{ "AutofillEnableVirtualCard", base::FEATURE_DISABLED_BY_DEFAULT}; +// When enabled, Autofill will attempt to find merchant promo/coupon/gift code +// fields when parsing forms. +const base::Feature kAutofillParseMerchantPromoCodeFields{ + "AutofillParseMerchantPromoCodeFields", base::FEATURE_DISABLED_BY_DEFAULT}; + // When enabled, the Save Card infobar will be dismissed by a user initiated // navigation other than one caused by submitted form. const base::Feature kAutofillSaveCardDismissOnNavigation{
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index cb5ef41..8f28feb 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -31,6 +31,7 @@ kAutofillEnableSaveCardInfoBarAccountIndicationFooter; extern const base::Feature kAutofillEnableToolbarStatusChip; extern const base::Feature kAutofillEnableVirtualCard; +extern const base::Feature kAutofillParseMerchantPromoCodeFields; extern const base::Feature kAutofillSaveCardDismissOnNavigation; extern const base::Feature kAutofillSaveCardInfobarEditSupport; extern const base::Feature kAutofillSortSuggestionsBasedOnOfferPresence;
diff --git a/components/autofill/core/common/logging/log_buffer.cc b/components/autofill/core/common/logging/log_buffer.cc index 961e66e4..0020815c 100644 --- a/components/autofill/core/common/logging/log_buffer.cc +++ b/components/autofill/core/common/logging/log_buffer.cc
@@ -238,10 +238,10 @@ namespace { // Highlights the first |needle| in |haystack| by wrapping it in <b> tags. -template <typename STRING_TYPE> -LogBuffer HighlightValueInternal(base::BasicStringPiece<STRING_TYPE> haystack, - base::BasicStringPiece<STRING_TYPE> needle) { - using StringPieceT = base::BasicStringPiece<STRING_TYPE>; +template <typename CharT> +LogBuffer HighlightValueInternal(base::BasicStringPiece<CharT> haystack, + base::BasicStringPiece<CharT> needle) { + using StringPieceT = base::BasicStringPiece<CharT>; LogBuffer buffer; size_t pos = haystack.find(needle); if (pos == StringPieceT::npos || needle.empty()) {
diff --git a/components/autofill_assistant/browser/service/server_url_fetcher.cc b/components/autofill_assistant/browser/service/server_url_fetcher.cc index 5657d88..e95c131f9 100644 --- a/components/autofill_assistant/browser/service/server_url_fetcher.cc +++ b/components/autofill_assistant/browser/service/server_url_fetcher.cc
@@ -40,19 +40,19 @@ } GURL ServerUrlFetcher::GetSupportsScriptEndpoint() const { - url::StringPieceReplacements<std::string> script_replacements; + GURL::Replacements script_replacements; script_replacements.SetPathStr(kScriptEndpoint); return server_url_.ReplaceComponents(script_replacements); } GURL ServerUrlFetcher::GetNextActionsEndpoint() const { - url::StringPieceReplacements<std::string> action_replacements; + GURL::Replacements action_replacements; action_replacements.SetPathStr(kActionEndpoint); return server_url_.ReplaceComponents(action_replacements); } GURL ServerUrlFetcher::GetTriggerScriptsEndpoint() const { - url::StringPieceReplacements<std::string> trigger_replacements; + GURL::Replacements trigger_replacements; trigger_replacements.SetPathStr(kTriggersEndpoint); return server_url_.ReplaceComponents(trigger_replacements); }
diff --git a/components/autofill_assistant/browser/service/service_request_sender_impl.cc b/components/autofill_assistant/browser/service/service_request_sender_impl.cc index eabeb73..ececd87 100644 --- a/components/autofill_assistant/browser/service/service_request_sender_impl.cc +++ b/components/autofill_assistant/browser/service/service_request_sender_impl.cc
@@ -101,7 +101,7 @@ std::string query_str = base::StrCat({"key=", api_key}); // query_str must remain valid until ReplaceComponents() has returned. - url::StringPieceReplacements<std::string> add_key; + GURL::Replacements add_key; add_key.SetQueryStr(query_str); GURL modified_url = url.ReplaceComponents(add_key);
diff --git a/components/browser_sync/active_devices_provider_impl_unittest.cc b/components/browser_sync/active_devices_provider_impl_unittest.cc index 5ab9233c..215a2a6 100644 --- a/components/browser_sync/active_devices_provider_impl_unittest.cc +++ b/components/browser_sync/active_devices_provider_impl_unittest.cc
@@ -38,7 +38,8 @@ "device_id", "manufacturer_name", "model_name", last_updated_timestamp, base::TimeDelta::FromMinutes(kPulseIntervalMinutes), /*send_tab_to_self_receiving_enabled=*/false, - /*sharing_info=*/base::nullopt, fcm_registration_token, + /*sharing_info=*/base::nullopt, /*paask_info=*/base::nullopt, + fcm_registration_token, /*interested_data_types=*/syncer::ModelTypeSet()); }
diff --git a/components/cast_channel/libcast_socket_service.cc b/components/cast_channel/libcast_socket_service.cc index cba28623..426fd3c8 100644 --- a/components/cast_channel/libcast_socket_service.cc +++ b/components/cast_channel/libcast_socket_service.cc
@@ -6,7 +6,6 @@ #include "base/callback_helpers.h" #include "base/memory/ptr_util.h" -#include "base/task/post_task.h" #include "components/cast_channel/cast_message_util.h" #include "components/cast_channel/cast_socket.h" #include "components/cast_channel/cast_transport.h" @@ -164,7 +163,7 @@ LibcastSocketService::LibcastSocketService() : openscreen_task_runner_( // NOTE: Network service must be accessed on UI thread. - base::CreateSingleThreadTaskRunner({content::BrowserThread::UI})), + content::GetUIThreadTaskRunner({})), socket_factory_(this, &openscreen_task_runner_), tls_factory_(openscreen::TlsConnectionFactory::CreateFactory( &socket_factory_,
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index 51d976c..fc99e839 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -686,8 +686,8 @@ "url": "https://oak.ct.letsencrypt.org/2023/", "mmd": 86400, "state": { - "qualified": { - "timestamp": "2020-08-18T00:00:00Z" + "usable": { + "timestamp": "2021-03-01T19:24:00Z" } }, "temporal_interval": { @@ -710,8 +710,8 @@ "url": "https://ct.trustasia.com/log2020/", "mmd": 86400, "state": { - "qualified": { - "timestamp": "2020-08-18T00:00:00Z" + "retired": { + "timestamp": "2020-12-01T00:00:00Z" } }, "temporal_interval": { @@ -726,8 +726,8 @@ "url": "https://ct.trustasia.com/log2021/", "mmd": 86400, "state": { - "qualified": { - "timestamp": "2020-08-18T00:00:00Z" + "retired": { + "timestamp": "2020-12-01T00:00:00Z" } }, "temporal_interval": { @@ -742,8 +742,8 @@ "url": "https://ct.trustasia.com/log2022/", "mmd": 86400, "state": { - "qualified": { - "timestamp": "2020-08-18T00:00:00Z" + "usable": { + "timestamp": "2021-03-01T19:24:00Z" } }, "temporal_interval": { @@ -758,8 +758,8 @@ "url": "https://ct.trustasia.com/log2023/", "mmd": 86400, "state": { - "qualified": { - "timestamp": "2020-08-18T00:00:00Z" + "usable": { + "timestamp": "2021-03-01T19:24:00Z" } }, "temporal_interval": {
diff --git a/components/crash/core/app/breakpad_linux.cc b/components/crash/core/app/breakpad_linux.cc index 9e850c0..00009da 100644 --- a/components/crash/core/app/breakpad_linux.cc +++ b/components/crash/core/app/breakpad_linux.cc
@@ -41,6 +41,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/threading/thread_checker.h" +#include "build/branding_buildflags.h" #include "build/build_config.h" #include "components/crash/core/app/breakpad_linux_impl.h" #include "components/crash/core/app/crash_reporter_client.h" @@ -2077,6 +2078,15 @@ void SetChannelCrashKey(const std::string& channel) { static crash_reporter::CrashKeyString<16> channel_key("channel"); channel_key.Set(channel); +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + if (channel == "extended") { + // Extended stable reports as stable (empty string) with an extra bool. + static crash_reporter::CrashKeyString<5> extended_stable_key( + "extended_stable_channel"); + extended_stable_key.Set("true"); + channel_key.Set(""); + } +#endif } #if defined(OS_ANDROID)
diff --git a/components/crash/core/app/crashpad_linux.cc b/components/crash/core/app/crashpad_linux.cc index 8eb3f407..811d472 100644 --- a/components/crash/core/app/crashpad_linux.cc +++ b/components/crash/core/app/crashpad_linux.cc
@@ -136,6 +136,11 @@ #if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Empty means stable. const bool allow_empty_channel = true; + if (channel == "extended") { + // Extended stable reports as stable (empty string) with an extra bool. + channel.clear(); + annotations["extended_stable_channel"] = "true"; + } #else const bool allow_empty_channel = false; #endif
diff --git a/components/crash/core/app/crashpad_mac.mm b/components/crash/core/app/crashpad_mac.mm index eb675321..2be2fd8 100644 --- a/components/crash/core/app/crashpad_mac.mm +++ b/components/crash/core/app/crashpad_mac.mm
@@ -65,7 +65,16 @@ channel = [channel substringFromIndex:[@"arm64-" length]]; else if ([channel hasPrefix:@"universal-"]) channel = [channel substringFromIndex:[@"universal-" length]]; - process_annotations["channel"] = base::SysNSStringToUTF8(channel); +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + if ([channel isEqual:@"extended"]) { + // Extended stable reports as stable with an extra bool. + channel = @""; + process_annotations["extended_stable_channel"] = "true"; + } +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) + if (allow_empty_channel || [channel length]) { + process_annotations["channel"] = base::SysNSStringToUTF8(channel); + } } NSString* version =
diff --git a/components/crash/core/app/crashpad_win.cc b/components/crash/core/app/crashpad_win.cc index c66a6df..686be796 100644 --- a/components/crash/core/app/crashpad_win.cc +++ b/components/crash/core/app/crashpad_win.cc
@@ -41,6 +41,11 @@ #if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Empty means stable. const bool allow_empty_channel = true; + if (channel_name == L"extended") { + // Extended stable reports as stable (empty string) with an extra bool. + channel_name.clear(); + (*annotations)["extended_stable_channel"] = "true"; + } #else const bool allow_empty_channel = false; #endif
diff --git a/components/embedder_support/user_agent_utils.cc b/components/embedder_support/user_agent_utils.cc index cf596ae..569518f 100644 --- a/components/embedder_support/user_agent_utils.cc +++ b/components/embedder_support/user_agent_utils.cc
@@ -154,7 +154,8 @@ #if defined(OS_ANDROID) void SetDesktopUserAgentOverride(content::WebContents* web_contents, - const blink::UserAgentMetadata& metadata) { + const blink::UserAgentMetadata& metadata, + bool override_in_new_tabs) { const char kLinuxInfoStr[] = "X11; Linux x86_64"; std::string product = version_info::GetProductNameAndVersionForUserAgent(); @@ -169,7 +170,7 @@ spoofed_ua.ua_metadata_override->model = std::string(); spoofed_ua.ua_metadata_override->mobile = false; - web_contents->SetUserAgentOverride(spoofed_ua, false); + web_contents->SetUserAgentOverride(spoofed_ua, override_in_new_tabs); } #endif // OS_ANDROID
diff --git a/components/embedder_support/user_agent_utils.h b/components/embedder_support/user_agent_utils.h index a6306c7..52e1148 100644 --- a/components/embedder_support/user_agent_utils.h +++ b/components/embedder_support/user_agent_utils.h
@@ -36,8 +36,12 @@ #if defined(OS_ANDROID) // This sets a user agent string to simulate a desktop user agent on mobile. +// If |override_in_new_tabs| is true, and the first navigation in the tab is +// renderer initiated, then is-overriding-user-agent is set to true for the +// NavigationEntry. void SetDesktopUserAgentOverride(content::WebContents* web_contents, - const blink::UserAgentMetadata& metadata); + const blink::UserAgentMetadata& metadata, + bool override_in_new_tabs); #endif } // namespace embedder_support
diff --git a/components/error_page/common/BUILD.gn b/components/error_page/common/BUILD.gn index a47979b..547e9cc 100644 --- a/components/error_page/common/BUILD.gn +++ b/components/error_page/common/BUILD.gn
@@ -24,6 +24,7 @@ "//components/strings", "//components/url_formatter", "//net", + "//third_party/zlib/google:compression_utils", "//ui/base", "//url", ]
diff --git a/components/error_page/common/DEPS b/components/error_page/common/DEPS index 4a6578fb..3fd98d7 100644 --- a/components/error_page/common/DEPS +++ b/components/error_page/common/DEPS
@@ -4,5 +4,6 @@ "+components/strings", "+crypto", "+net", + "+third_party/zlib/google", "+ui/base", ]
diff --git a/components/error_page/common/alt_game_images.cc b/components/error_page/common/alt_game_images.cc index 25fe750..9aa89e9 100644 --- a/components/error_page/common/alt_game_images.cc +++ b/components/error_page/common/alt_game_images.cc
@@ -7,2771 +7,1858 @@ #include "base/base64.h" #include "base/base64url.h" #include "base/rand_util.h" +#include "base/stl_util.h" #include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "crypto/encryptor.h" #include "crypto/symmetric_key.h" +#include "third_party/zlib/google/compression_utils.h" namespace error_page { namespace { -const char* kAltGameImages1x[] = { - (char[]){ - 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, - }, - (char[]){ - 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, - }, - (char[]){ - 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, - }, - (char[]){ - 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, - }, - (char[]){ - 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, - }, - (char[]){ - 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 kPngMagicBytes[] = {0x89, 0x50, 0x4E, 0x47, + 0x0D, 0x0A, 0x1A, 0x0A}; +const uint8_t kAltGameImages1x[] = { + 0x45, 0xb3, 0x21, 0x0, 0x88, 0xc2, 0x11, 0xbc, 0xcb, 0xd7, 0x66, 0xa9, + 0xf7, 0xb0, 0xab, 0xf1, 0x50, 0xb3, 0xc, 0x4a, 0x6b, 0x2f, 0xdc, 0xcd, + 0x62, 0x2e, 0x11, 0x24, 0xd3, 0x9f, 0xa, 0x11, 0xb7, 0x3d, 0x91, 0x25, + 0xd, 0x9d, 0x5e, 0x2a, 0xac, 0x2b, 0xf3, 0x63, 0x2d, 0xda, 0x7f, 0x80, + 0x1b, 0x65, 0xd8, 0x98, 0xce, 0xde, 0xc2, 0x21, 0xdb, 0x86, 0x4f, 0x27, + 0x96, 0x10, 0xac, 0x42, 0x60, 0xae, 0x9d, 0x2, 0xa1, 0xd5, 0x25, 0x99, + 0x83, 0x49, 0x1d, 0xb1, 0x7f, 0x24, 0x12, 0x81, 0x2d, 0xd0, 0x69, 0x1b, + 0x3d, 0xdf, 0xeb, 0x5, 0xb1, 0x9f, 0xd7, 0xd6, 0x7d, 0x9c, 0xe1, 0xf5, + 0xb1, 0xcc, 0x6f, 0xed, 0x36, 0x5a, 0xad, 0xe1, 0xe9, 0x8b, 0xc2, 0x25, + 0x76, 0x3b, 0xf, 0xfd, 0x7f, 0xb3, 0x25, 0xfd, 0x4e, 0xd7, 0x7b, 0x71, + 0x75, 0x96, 0xc4, 0x87, 0x2d, 0x1a, 0x5d, 0x94, 0x7c, 0xa4, 0x4a, 0xf2, + 0x8c, 0xa1, 0xd, 0x36, 0xc9, 0xdd, 0x29, 0x2a, 0xfb, 0x19, 0xce, 0x9a, + 0x33, 0xb3, 0x55, 0x4d, 0x4e, 0xf1, 0xf1, 0xa8, 0xb5, 0xbd, 0xa9, 0xa5, + 0x5d, 0x78, 0x37, 0x6, 0xce, 0x69, 0xf6, 0xeb, 0xdc, 0xeb, 0x29, 0x19, + 0x23, 0xce, 0xb0, 0x3b, 0x2, 0x60, 0x59, 0xb9, 0x9d, 0x10, 0x21, 0x22, + 0xe4, 0x71, 0xb5, 0x71, 0x5f, 0xdf, 0x98, 0xf0, 0x54, 0xd8, 0x83, 0xcf, + 0xd7, 0xc9, 0xde, 0x42, 0x76, 0x72, 0xe3, 0xe2, 0xe7, 0x96, 0x4c, 0x37, + 0x2b, 0xb7, 0x3c, 0x72, 0x29, 0xf9, 0x75, 0xaa, 0x3, 0xa8, 0xd, 0x34, + 0x58, 0x6d, 0x74, 0x2a, 0x4c, 0xaf, 0xc2, 0xc1, 0xc8, 0x1c, 0xf, 0xea, + 0xec, 0x28, 0x1a, 0x2, 0xbc, 0xd7, 0xa9, 0x78, 0x7, 0x77, 0xb2, 0x1d, + 0x94, 0x83, 0xfb, 0xd5, 0x8d, 0xe4, 0xc0, 0xdf, 0x28, 0xa1, 0xd9, 0x5d, + 0x2b, 0x9f, 0x86, 0x96, 0x85, 0x31, 0xe5, 0xa9, 0xfe, 0x35, 0x30, 0x4f, + 0xfe, 0x26, 0x1, 0xa, 0x35, 0x8c, 0x3f, 0xff, 0x37, 0x21, 0x4f, 0x30, + 0x4c, 0x12, 0xfb, 0x52, 0x85, 0xd4, 0x4e, 0x6f, 0xe5, 0xca, 0xfa, 0x1c, + 0xea, 0xea, 0x83, 0xfb, 0xf2, 0x8a, 0x2d, 0x51, 0xf, 0x45, 0x25, 0xda, + 0xba, 0x92, 0x2c, 0x58, 0x9, 0x54, 0x16, 0x2e, 0x3e, 0x7b, 0x23, 0x77, + 0x8, 0xfa, 0x32, 0x97, 0x6e, 0x94, 0x9f, 0xce, 0x4d, 0xe5, 0x3d, 0x8a, + 0x91, 0xd6, 0x32, 0x4d, 0x82, 0x9a, 0xe5, 0x6, 0x58, 0x6e, 0xb2, 0xea, + 0x1d, 0x45, 0xed, 0x4e, 0x1f, 0x9f, 0x41, 0xfe, 0xe2, 0xdd, 0xf3, 0xd9, + 0x6a, 0xd, 0xe7, 0xf2, 0xa4, 0xbe, 0x30, 0x6, 0x77, 0x66, 0x71, 0x80, + 0x51, 0xf6, 0x2f, 0x1d, 0x5c, 0x9f, 0x1c, 0xc9, 0xec, 0xeb, 0x23, 0xdc, + 0xd0, 0xa2, 0xab, 0x26, 0x10, 0x8e, 0xb4, 0x58, 0x84, 0xb5, 0xcc, 0x7b, + 0x75, 0x29, 0x61, 0x4e, 0xf3, 0xc3, 0x9b, 0x7f, 0x21, 0x8a, 0x96, 0x6b, + 0x47, 0x30, 0x88, 0x5d, 0xce, 0xfc, 0x1e, 0xdb, 0xd3, 0x7, 0xf2, 0x6a, + 0x82, 0x33, 0xdc, 0x66, 0x6a, 0x37, 0xac, 0x26, 0xd7, 0xcc, 0x35, 0x38, + 0x9b, 0x86, 0x8d, 0xc1, 0xeb, 0xf6, 0xc, 0xe9, 0xab, 0x49, 0xc8, 0x5e, + 0xe5, 0x15, 0x2d, 0xbb, 0xb3, 0x8d, 0x13, 0xa8, 0x8f, 0x26, 0xd2, 0xee, + 0xb8, 0x43, 0x37, 0x3b, 0x22, 0xf1, 0x4, 0xd2, 0x79, 0xa3, 0xfe, 0xbe, + 0x87, 0x4f, 0x46, 0xc6, 0xa9, 0xe4, 0xb5, 0xa7, 0xee, 0x52, 0x2d, 0x37, + 0x90, 0x6, 0x47, 0x86, 0xa2, 0x5a, 0xe3, 0xf6, 0x4e, 0x54, 0x51, 0xbc, + 0xa0, 0xc6, 0x86, 0xe0, 0xd, 0x60, 0xb7, 0xfc, 0xed, 0xb9, 0xc2, 0xe, + 0x3, 0x53, 0x76, 0xd2, 0x99, 0x66, 0xbe, 0x46, 0x4d, 0x6f, 0x21, 0x75, + 0x96, 0xc, 0x96, 0xa3, 0xe7, 0xd, 0x2a, 0xb4, 0x73, 0x99, 0xed, 0xff, + 0xb9, 0x13, 0x26, 0x5f, 0x44, 0x3a, 0xc5, 0xce, 0x7e, 0x32, 0x9d, 0xd7, + 0xf1, 0x13, 0x34, 0x4f, 0xb4, 0x21, 0x3c, 0x1, 0xcc, 0x36, 0xd6, 0x99, + 0xdc, 0x49, 0x18, 0xcb, 0xac, 0x42, 0xc6, 0xb4, 0x77, 0x5d, 0xee, 0x9a, + 0xd3, 0xbf, 0xac, 0x78, 0xbc, 0x6c, 0x5e, 0xda, 0xcf, 0x3e, 0xdd, 0xdf, + 0x19, 0xb1, 0xb2, 0xba, 0xba, 0x1b, 0xf8, 0x3b, 0x2b, 0x3, 0xf, 0x21, + 0xbd, 0xaa, 0x93, 0x7, 0x2c, 0x84, 0x9, 0x80, 0x99, 0xe0, 0xe1, 0xd3, + 0xf3, 0xe9, 0xf9, 0xf2, 0x2b, 0x79, 0x80, 0xb9, 0xd3, 0xb5, 0x5f, 0xc7, + 0xd4, 0x2d, 0x62, 0xf4, 0x87, 0xf8, 0x15, 0xf, 0x1b, 0x42, 0x86, 0x69, + 0x44, 0x87, 0x58, 0x83, 0xb2, 0x28, 0x49, 0x20, 0x26, 0x64, 0xa9, 0x1b, + 0xa8, 0xa8, 0x19, 0x2, 0x7b, 0x65, 0x8f, 0xa3, 0x65, 0xf, 0xec, 0xb5, + 0xad, 0xfb, 0xc4, 0x82, 0x37, 0x4f, 0xcf, 0x9b, 0xdf, 0xcd, 0xd2, 0x1f, + 0x55, 0xbd, 0x5f, 0xea, 0xc3, 0xba, 0xbf, 0x1b, 0x7a, 0xd1, 0x6d, 0x48, + 0xab, 0xea, 0x52, 0x9a, 0xa5, 0x3f, 0x7e, 0x72, 0x15, 0x12, 0x70, 0x40, + 0x81, 0xd8, 0xdf, 0xb0, 0x9, 0x8, 0x74, 0xba, 0xfe, 0x31, 0xb3, 0x82, + 0x9c, 0xb4, 0x70, 0xe0, 0xdd, 0x89, 0x28, 0x81, 0x61, 0xce, 0xe, 0x9f, + 0x2b, 0x56, 0x15, 0x24, 0x37, 0x35, 0x6a, 0x9d, 0xc8, 0x88, 0x0, 0xa8, + 0x39, 0xb2, 0x30, 0xa5, 0xf0, 0x42, 0xe5, 0x1f, 0x49, 0xea, 0xc4, 0xce, + 0xae, 0xfb, 0x96, 0x94, 0xe1, 0x4c, 0xd0, 0xe5, 0x6a, 0xf9, 0x8, 0x9a, + 0x6e, 0x4c, 0x41, 0xad, 0x9c, 0xac, 0x22, 0x22, 0x86, 0x60, 0x1a, 0x3f, + 0x29, 0x3d, 0x2f, 0x29, 0x8e, 0xd3, 0x77, 0xd7, 0xb2, 0xcc, 0xf0, 0x81, + 0xe2, 0xe2, 0xb6, 0xf3, 0x39, 0x97, 0xd, 0x5f, 0xd4, 0x39, 0x43, 0x16, + 0xf0, 0x53, 0xa9, 0x4c, 0x9f, 0x53, 0xd4, 0xf2, 0xd6, 0x85, 0x45, 0xd1, + 0xf2, 0xc1, 0x7b, 0x7f, 0x21, 0xa1, 0x7f, 0xc8, 0xb5, 0xd2, 0xc, 0xd, + 0xb8, 0x71, 0x37, 0x77, 0xcc, 0xb6, 0x23, 0x9, 0x41, 0x82, 0xb0, 0x5d, + 0x6c, 0x34, 0x62, 0xae, 0x95, 0x7f, 0x59, 0xc6, 0x40, 0x10, 0xc4, 0x2b, + 0x4d, 0xc4, 0x8a, 0xad, 0x7c, 0x78, 0x21, 0x23, 0xd3, 0xb3, 0x32, 0x7d, + 0x76, 0x96, 0x72, 0x19, 0xfd, 0xdd, 0xa6, 0x1a, 0xda, 0x4f, 0x3e, 0x7d, + 0x5a, 0x6a, 0xd3, 0x6, 0x88, 0xf1, 0xa9, 0x59, 0xe0, 0xa2, 0xc9, 0x98, + 0xc4, 0xdc, 0x8c, 0xac, 0xe4, 0xdf, 0x71, 0x36, 0x63, 0x61, 0x7e, 0x9b, + 0x27, 0x6a, 0x81, 0x9f, 0xa2, 0x1c, 0xe4, 0x7a, 0x28, 0x86, 0xc7, 0xf3, + 0x74, 0x86, 0x13, 0xc8, 0xa4, 0x4c, 0xf1, 0xcb, 0x80, 0xa4, 0x96, 0xe3, + 0xf4, 0xc8, 0x2d, 0x11, 0xbb, 0xa3, 0x17, 0x24, 0xae, 0xf1, 0x8a, 0xc4, + 0x90, 0x24, 0xd2, 0xa5, 0x4e, 0xa, 0xc, 0xe7, 0x72, 0xb8, 0xc8, 0xa9, + 0x6e, 0x68, 0x10, 0x12, 0x99, 0xb8, 0xdd, 0xa1, 0x51, 0xec, 0xcb, 0x45, + 0x18, 0xed, 0xec, 0x77, 0x84, 0x3a, 0x3d, 0x14, 0xd9, 0xa7, 0x7f, 0xcc, + 0x41, 0x8f, 0xd0, 0x82, 0xfa, 0x23, 0x80, 0xba, 0x35, 0x42, 0xca, 0x35, + 0x9d, 0xd6, 0x2a, 0xc4, 0x0, 0xd5, 0x1c, 0x6a, 0xf8, 0xcb, 0x40, 0x29, + 0x41, 0x7b, 0x28, 0x27, 0x7d, 0x3, 0x23, 0x6b, 0x98, 0xf1, 0xe8, 0x2b, + 0x12, 0x5d, 0x6b, 0x8a, 0xa1, 0x7c, 0x9, 0x7f, 0x1, 0xf6, 0xa5, 0x10, + 0xd3, 0x4d, 0x39, 0xc1, 0x92, 0x78, 0xcd, 0x3f, 0xc0, 0xc8, 0xfe, 0xc4, + 0x28, 0x1, 0x22, 0x26, 0x76, 0x46, 0xee, 0x13, 0x43, 0xb9, 0xa7, 0x91, + 0xd8, 0x2d, 0xaa, 0xeb, 0xfe, 0x9a, 0xb2, 0x3d, 0x44, 0x31, 0xc3, 0xb4, + 0xb6, 0xf8, 0x34, 0xc8, 0x4c, 0xe5, 0xf8, 0x1, 0x1, 0x2c, 0xe4, 0x64, + 0xc9, 0x90, 0x19, 0xa1, 0xc6, 0xad, 0x23, 0x5d, 0x89, 0x64, 0x25, 0xcc, + 0xe6, 0x6, 0xea, 0xc5, 0x13, 0x3b, 0x79, 0x15, 0xcd, 0x12, 0xdd, 0x26, + 0xd6, 0x42, 0x9a, 0xa0, 0x14, 0x1e, 0x94, 0xae, 0x9, 0xf2, 0x3f, 0xba, + 0xca, 0xb7, 0x97, 0xd3, 0x86, 0x37, 0xd1, 0x61, 0x8b, 0x47, 0x2e, 0xdf, + 0xe6, 0x5, 0x6d, 0x9b, 0x4f, 0x8, 0xf3, 0x61, 0x45, 0xa3, 0x90, 0x28, + 0xfc, 0x8d, 0x9c, 0x57, 0x63, 0x75, 0xdc, 0xb0, 0xda, 0xed, 0xee, 0x86, + 0xb0, 0xf8, 0xa3, 0x82, 0x3b, 0xf8, 0xf9, 0x41, 0x1f, 0x4d, 0xf1, 0x4c, + 0x78, 0xca, 0x26, 0x45, 0x39, 0xd4, 0xca, 0x8f, 0xd7, 0xdf, 0x8a, 0x43, + 0x5b, 0x2d, 0xea, 0xd9, 0xd, 0xa4, 0x3b, 0x6e, 0x9f, 0xf8, 0xa9, 0x4f, + 0x57, 0x67, 0x9, 0xfe, 0x37, 0x89, 0xcf, 0x92, 0x42, 0xcb, 0xa, 0x1e, + 0xd5, 0x26, 0xdf, 0x55, 0xad, 0x3b, 0x6d, 0x1c, 0xb7, 0xf8, 0x43, 0x1a, + 0xb4, 0xb8, 0x1e, 0x12, 0xa5, 0x21, 0x7c, 0xc6, 0xaf, 0x3d, 0xe4, 0x96, + 0xeb, 0xa1, 0xbe, 0x4c, 0xc3, 0x2d, 0x64, 0x23, 0xfc, 0x3, 0x37, 0x6a, + 0xbd, 0xd1, 0xc0, 0xdb, 0x1e, 0x71, 0xc0, 0x54, 0x94, 0xcd, 0xf9, 0x5d, + 0x74, 0xce, 0x16, 0xaa, 0xec, 0xb5, 0x9d, 0xa, 0x74, 0xdb, 0xfd, 0xcd, + 0xc6, 0x8e, 0xfe, 0xe2, 0x84, 0x12, 0xc4, 0x32, 0xc, 0xd, 0x8e, 0xee, + 0x49, 0x2d, 0xef, 0x3e, 0x2d, 0x90, 0x3b, 0xab, 0x40, 0x4a, 0xff, 0x22, + 0xce, 0xf7, 0x22, 0x96, 0x25, 0x71, 0x4, 0xc8, 0x18, 0x5c, 0xdc, 0x5, + 0x80, 0x3f, 0xde, 0x1c, 0x4f, 0xf3, 0x1b, 0x9f, 0x2, 0xa5, 0xbd, 0x79, + 0x9b, 0x6d, 0x12, 0xc3, 0xb3, 0x63, 0x7f, 0x19, 0xe9, 0xcf, 0xdb, 0x51, + 0xa5, 0x7c, 0x7, 0xe8, 0x83, 0x5d, 0xef, 0xe5, 0xb4, 0x3c, 0x10, 0x3d, + 0xaa, 0x96, 0xeb, 0x6b, 0x67, 0x1e, 0x5a, 0xca, 0x46, 0xa4, 0x4a, 0x49, + 0xe, 0xc9, 0x64, 0xe2, 0x1d, 0xbf, 0xa3, 0x8d, 0xa2, 0x71, 0xc2, 0x36, + 0x23, 0x6b, 0xb1, 0x57, 0x3b, 0xf5, 0x7f, 0xee, 0x1c, 0xce, 0x27, 0x81, + 0x6d, 0xcb, 0x22, 0x66, 0x58, 0x20, 0xd4, 0xcc, 0x72, 0x59, 0xcb, 0xbc, + 0xb6, 0x7a, 0x64, 0xf2, 0x5a, 0x43, 0xcc, 0xeb, 0x88, 0x88, 0x54, 0x89, + 0x33, 0xfe, 0x96, 0x6c, 0xa0, 0x81, 0xc7, 0x33, 0x1b, 0x50, 0x25, 0x18, + 0xbf, 0x30, 0x1e, 0xa6, 0x41, 0x74, 0xf, 0x4a, 0x3f, 0x55, 0xb2, 0x3f, + 0xb8, 0xa1, 0x92, 0x19, 0x4a, 0x86, 0x81, 0xcd, 0x18, 0xcd, 0xcb, 0x8c, + 0xe9, 0x34, 0xf9, 0xfc, 0x2a, 0x70, 0x1d, 0x13, 0x33, 0x68, 0x9b, 0xca, + 0x38, 0x10, 0x3c, 0x4, 0xb5, 0x7f, 0x70, 0x19, 0xca, 0xd2, 0xb5, 0x36, + 0x33, 0x5b, 0x9e, 0x84, 0xac, 0x4b, 0x42, 0xe5, 0x2d, 0xc0, 0x35, 0x1c, + 0x81, 0xdb, 0xa2, 0x54, 0xf9, 0x59, 0xfd, 0x1f, 0x76, 0x5b, 0x8b, 0x5b, + 0x5f, 0xf3, 0x7b, 0x80, 0x8b, 0xaf, 0x5d, 0xdc, 0x44, 0x9a, 0x48, 0x56, + 0x37, 0xe9, 0x3b, 0x3d, 0x4e, 0xc1, 0xe7, 0x75, 0xb0, 0xf8, 0x8b, 0xd9, + 0xbd, 0x33, 0x46, 0xca, 0xbf, 0xd2, 0xaf, 0x69, 0xff, 0x9e, 0xc6, 0x6d, + 0xb3, 0x82, 0x93, 0x59, 0x5f, 0x37, 0x34, 0x2e, 0x5, 0xe2, 0x34, 0x2f, + 0x9e, 0x87, 0x31, 0xb0, 0x68, 0x73, 0x50, 0x8f, 0x97, 0x89, 0xb1, 0x68, + 0x6f, 0x56, 0x37, 0x5d, 0x35, 0x25, 0x39, 0xd5, 0xfa, 0xfb, 0x90, 0x9e, + 0x24, 0xcf, 0xa7, 0x71, 0x1c, 0x7a, 0x78, 0x2c, 0xaf, 0x36, 0xf5, 0x22, + 0x9c, 0xfe, 0xef, 0x4d, 0xac, 0x3c, 0x56, 0x97, 0xb4, 0x8a, 0xc6, 0x92, + 0xd3, 0xa5, 0x7, 0x4b, 0x21, 0x89, 0xe0, 0xd, 0x7b, 0xf9, 0xe0, 0x6e, + 0x72, 0x69, 0xd5, 0x30, 0xcc, 0xc9, 0x25, 0xf7, 0x4, 0xdd, 0x4b, 0x4e, + 0x4e, 0x4d, 0xa5, 0x73, 0x9a, 0x27, 0x21, 0x9c, 0xf8, 0xd0, 0x79, 0x28, + 0x7, 0x6c, 0x47, 0xdf, 0x3c, 0xe, 0x27, 0xa1, 0xf6, 0x49, 0x90, 0x15, + 0xde, 0xf, 0x24, 0x1b, 0xdc, 0x42, 0x5c, 0xf7, 0xd2, 0x3f, 0x19, 0x2, + 0x3b, 0xf6, 0x29, 0x67, 0xaa, 0xfe, 0xe0, 0x1f, 0x96, 0x4a, 0x11, 0x3b, + 0x97, 0x55, 0x3c, 0x71, 0x0, 0xd9, 0x3d, 0x27, 0x6a, 0x23, 0xb1, 0xe3, + 0x80, 0x6c, 0x46, 0xc, 0xb6, 0x18, 0xc0, 0x65, 0xe3, 0x6f, 0x10, 0x95, + 0xd4, 0x96, 0xa3, 0x6f, 0x53, 0x81, 0x1, 0xec, 0xe0, 0xd, 0xfd, 0xfb, + 0xd1, 0x48, 0x54, 0x51, 0x73, 0x7, 0x85, 0xa8, 0xac, 0xbd, 0xca, 0x3c, + 0x2b, 0xd0, 0xec, 0x34, 0x47, 0xc7, 0x9d, 0x5b, 0xff, 0x3f, 0x85, 0x6b, + 0x7b, 0x8a, 0x1a, 0xf9, 0xdf, 0x6a, 0xf7, 0x5d, 0x34, 0x91, 0xbf, 0x7d, + 0xe4, 0xf0, 0xbd, 0xc, 0xf6, 0x6b, 0x18, 0x86, 0xb6, 0x12, 0x22, 0x8b, + 0x1, 0xbe, 0x61, 0x9f, 0xc8, 0x37, 0xcc, 0x5b, 0x80, 0x18, 0xc6, 0xbf, + 0x3d, 0x22, 0xd7, 0xb0, 0x8, 0xf2, 0x65, 0x4e, 0xcd, 0xa3, 0xc3, 0x18, + 0x67, 0x14, 0xd3, 0x43, 0x1a, 0x3b, 0x5a, 0x46, 0xd, 0x7, 0x5e, 0x63, + 0x6, 0x8a, 0x13, 0x5e, 0x54, 0x70, 0x8, 0x24, 0x1, 0x7b, 0xfc, 0xa3, + 0x83, 0xd4, 0x1, 0xb6, 0xa, 0x19, 0xcc, 0x93, 0x80, 0xb5, 0xbe, 0x20, + 0x55, 0xa, 0xb1, 0xa6, 0xb1, 0x68, 0x97, 0xd, 0xdf, 0xff, 0x4e, 0x1e, + 0xb7, 0x2f, 0x96, 0xdb, 0xbe, 0x9b, 0x28, 0x2f, 0x93, 0x6c, 0xb9, 0x3b, + 0x5b, 0x17, 0x8c, 0xba, 0x17, 0xa4, 0xa8, 0xed, 0xd, 0x91, 0x34, 0x81, + 0xe0, 0xa7, 0xc5, 0x5d, 0x83, 0xd5, 0x71, 0xcf, 0xa5, 0xdc, 0xec, 0xc0, + 0x18, 0x93, 0xa, 0xcd, 0x91, 0xf9, 0x20, 0x82, 0xa6, 0xc0, 0xbe, 0xa5, + 0xa6, 0x96, 0x12, 0x24, 0xa3, 0xf5, 0x2a, 0xed, 0xf, 0xb2, 0x94, 0x58, + 0x73, 0xf7, 0xc0, 0x10, 0x9c, 0x1b, 0x80, 0x70, 0xf4, 0xde, 0xaf, 0x71, + 0x14, 0x3b, 0xc3, 0xed, 0x72, 0xa9, 0xe9, 0x86, 0x75, 0xfe, 0x35, 0x92, + 0xac, 0x67, 0x37, 0x4a, 0x96, 0x2c, 0x17, 0xb7, 0x51, 0xdc, 0xd6, 0xc1, + 0xc5, 0xea, 0x9a, 0x6, 0xe1, 0x2, 0x82, 0x9, 0x25, 0x83, 0x1d, 0x90, + 0x1, 0x90, 0x2, 0xb2, 0xfa, 0x2a, 0x43, 0xac, 0xa0, 0x1b, 0x84, 0x91, + 0x3c, 0x1c, 0x1d, 0x72, 0xb5, 0xe2, 0xc0, 0x3f, 0x6e, 0xf2, 0x66, 0xb0, + 0xf1, 0xad, 0x6c, 0xd8, 0x16, 0x5f, 0x45, 0x19, 0xb5, 0xd2, 0x28, 0x5, + 0xb3, 0xea, 0x32, 0x16, 0x85, 0xe2, 0x34, 0x33, 0x98, 0xf8, 0xfa, 0xbe, + 0x25, 0xe3, 0x9f, 0x58, 0x6a, 0xdb, 0x89, 0xb1, 0x52, 0x2a, 0xe3, 0x3e, + 0x78, 0xbf, 0xc1, 0x45, 0x6b, 0x88, 0xa9, 0xbd, 0x4c, 0x47, 0x47, 0x7d, + 0xee, 0x14, 0x4f, 0x51, 0x69, 0xad, 0x62, 0x9f, 0xdb, 0xc2, 0x90, 0x72, + 0xdf, 0x8d, 0xf6, 0x7c, 0xbc, 0xd8, 0x6e, 0x2a, 0xc0, 0xbd, 0x7a, 0xe3, + 0x5, 0x9, 0xd8, 0x73, 0xc2, 0xe1, 0xcb, 0xfa, 0xe5, 0xec, 0x84, 0x36, + 0xc1, 0xeb, 0xe7, 0xc8, 0x8a, 0x52, 0x11, 0xa4, 0x62, 0x3f, 0xf7, 0x68, + 0x45, 0x30, 0x37, 0x74, 0x5f, 0xba, 0x46, 0x81, 0xa1, 0x55, 0xb4, 0x98, + 0x57, 0x2e, 0x20, 0x82, 0x4, 0x89, 0xce, 0xe7, 0x1a, 0xa1, 0x9d, 0x9e, + 0xb6, 0x77, 0x1c, 0xa5, 0x45, 0x18, 0x85, 0x5a, 0x65, 0xd3, 0xb0, 0xa, + 0xfb, 0xf1, 0xcb, 0xb2, 0x82, 0x2c, 0xf6, 0xf9, 0x20, 0x56, 0x95, 0xe5, + 0x44, 0xb4, 0xa0, 0xda, 0x3, 0x49, 0x65, 0xa5, 0x18, 0xdc, 0x8c, 0xaa, + 0xa6, 0xad, 0x27, 0xc9, 0x94, 0x6e, 0x69, 0x5e, 0xd8, 0x41, 0x59, 0x6, + 0x37, 0xd0, 0xae, 0xe7, 0xec, 0x25, 0xfc, 0xb0, 0x96, 0xbf, 0xc4, 0xbe, + 0x62, 0xfa, 0xdd, 0x85, 0xd, 0x41, 0xb4, 0xce, 0x22, 0x1b, 0x64, 0xc6, + 0xa1, 0x3e, 0xc2, 0xb1, 0xce, 0x7d, 0x5f, 0x80, 0x6a, 0xb6, 0x1e, 0xc2, + 0x60, 0x55, 0x36, 0x2b, 0xff, 0xc0, 0xdf, 0xb1, 0xd5, 0xfd, 0x3e, 0xe2, + 0x9e, 0xaa, 0x21, 0xd2, 0x2e, 0xad, 0x56, 0x72, 0xb4, 0x7, 0xf1, 0x36, + 0x94, 0xc5, 0x5d, 0x55, 0xac, 0x75, 0xc7, 0xc1, 0xf8, 0x23, 0xba, 0x88, + 0x54, 0x8a, 0xae, 0x5b, 0x1b, 0x7c, 0x46, 0x10, 0xe6, 0x42, 0x9c, 0xbc, + 0x4f, 0x1f, 0x74, 0x83, 0xe6, 0x53, 0x18, 0xab, 0xe8, 0x5a, 0xa0, 0x3d, + 0x23, 0x7e, 0x12, 0x71, 0x66, 0xb2, 0x79, 0x6e, 0xa9, 0xb8, 0x1a, 0xd2, + 0xa3, 0xe3, 0x72, 0x91, 0xb6, 0x14, 0xde, 0x87, 0x17, 0x19, 0x5f, 0x63, + 0xb2, 0xe1, 0xf0, 0x91, 0x46, 0x42, 0xa8, 0x3b, 0xff, 0xf7, 0x22, 0xaf, + 0x10, 0x73, 0x76, 0x4, 0x0, 0xfd, 0xe4, 0xaf, 0x50, 0xc, 0x34, 0x5, + 0x76, 0xf, 0xc1, 0x36, 0xde, 0x59, 0xc9, 0x20, 0xde, 0xf9, 0x15, 0xe5, + 0xa2, 0xb3, 0x6c, 0xe7, 0x5, 0x74, 0x34, 0xc6, 0x4b, 0x85, 0xe6, 0x97, + 0x8e, 0xa5, 0x43, 0x10, 0xdd, 0x52, 0x65, 0x40, 0x94, 0x32, 0xe1, 0xa1, + 0xff, 0x2d, 0x93, 0x1e, 0xb6, 0x22, 0xe7, 0xfe, 0xd2, 0x87, 0x4e, 0xeb, + 0xf2, 0x20, 0xf8, 0xed, 0xf, 0x11, 0x4c, 0x77, 0x3b, 0x8e, 0x96, 0xb9, + 0x91, 0x85, 0x73, 0x66, 0x6, 0xd2, 0x60, 0x6d, 0x62, 0xc, 0x50, 0x30, + 0xcb, 0x2c, 0xb, 0x37, 0xe8, 0xf7, 0xe8, 0x71, 0xf, 0x29, 0x40, 0xca, + 0x96, 0xa, 0xe, 0x7e, 0x63, 0x85, 0xd7, 0x3e, 0x29, 0x5d, 0xd6, 0xbe, + 0x3, 0x64, 0xe1, 0x63, 0x43, 0x81, 0xea, 0x50, 0x22, 0x4a, 0xdd, 0xbd, + 0x2a, 0x7c, 0x7c, 0x94, 0x96, 0xf4, 0x9, 0x4a, 0x62, 0x3d, 0x5e, 0xe8, + 0x63, 0xbd, 0x5b, 0x49, 0xaf, 0x6a, 0x4f, 0x4f, 0xbf, 0x81, 0xfe, 0x61, + 0x98, 0xe9, 0x64, 0x2a, 0xf5, 0x94, 0x71, 0x8a, 0x74, 0x6b, 0xa7, 0x73, + 0x1, 0x84, 0xdc, 0x16, 0x13, 0x9b, 0xb0, 0xd7, 0x93, 0xd3, 0xd7, 0x84, + 0xc7, 0x37, 0xd3, 0xe4, 0x1c, 0x2, 0x8f, 0xf3, 0x32, 0x1d, 0xb0, 0x47, + 0x2b, 0x19, 0x77, 0x2c, 0x6c, 0xe1, 0x8e, 0xe2, 0x8a, 0xa9, 0x7f, 0x37, + 0x92, 0x0, 0x69, 0x91, 0x32, 0x3e, 0xb3, 0x9b, 0xeb, 0x8f, 0x71, 0x19, + 0x36, 0x52, 0x70, 0x63, 0xe, 0x7e, 0x56, 0xa2, 0xc2, 0x9, 0x35, 0x17, + 0x7c, 0x92, 0xc5, 0xe8, 0x58, 0x9a, 0x18, 0x1a, 0x85, 0x1d, 0xf0, 0xb6, + 0x78, 0x55, 0xc5, 0xa6, 0xea, 0x48, 0x3f, 0x1e, 0xf4, 0x8f, 0x68, 0x12, + 0xf6, 0x5f, 0xdd, 0xce, 0xaf, 0xaf, 0x10, 0x40, 0xb6, 0x15, 0x33, 0xda, + 0x3e, 0xc9, 0x4b, 0xf0, 0x74, 0x83, 0x67, 0x14, 0x33, 0x81, 0x2d, 0xda, + 0xbd, 0x77, 0xb7, 0xcd, 0x83, 0x41, 0xd1, 0x3e, 0x93, 0xd5, 0x90, 0x8a, + 0x64, 0x71, 0x80, 0x4f, 0xdc, 0x1, 0x51, 0xee, 0x9d, 0xf4, 0xf5, 0x1c, + 0x84, 0xef, 0xe4, 0x54, 0xdb, 0xab, 0x14, 0x83, 0xd9, 0xb6, 0x9c, 0xce, + 0x3a, 0x96, 0x1c, 0xae, 0xd8, 0xd5, 0x58, 0x9f, 0x20, 0xf3, 0x6f, 0x17, + 0xa3, 0xf4, 0xb8, 0xa2, 0xd9, 0xe0, 0xbc, 0x6b, 0xf, 0x76, 0x12, 0x83, + 0x5a, 0xb3, 0x40, 0xf1, 0x25, 0x5c, 0xcf, 0x5f, 0x30, 0x29, 0x6, 0x8f, + 0xb6, 0x62, 0x88, 0x21, 0x92, 0x23, 0xa, 0x69, 0x5, 0x56, 0xf3, 0xd1, + 0x6b, 0xa, 0xf5, 0x6b, 0x70, 0x1d, 0x3d, 0x88, 0x9f, 0x78, 0x9d, 0xb, + 0xfa, 0xf8, 0x5, 0xf9, 0x5c, 0xdd, 0x6b, 0x67, 0xcc, 0xf0, 0x3c, 0xa3, + 0xdf, 0x12, 0xbd, 0x9b, 0xb4, 0x4c, 0x2, 0x33, 0x8e, 0x33, 0xf4, 0xa7, + 0x48, 0x2c, 0xa, 0x1e, 0x4c, 0x49, 0xd4, 0xc9, 0x66, 0x7f, 0xf2, 0x5e, + 0x8d, 0x6a, 0xa8, 0x74, 0x6c, 0x66, 0xfc, 0x3f, 0x1b, 0xe3, 0x58, 0x94, + 0x30, 0x31, 0xee, 0x18, 0x6c, 0x82, 0xf6, 0x7a, 0x31, 0xd1, 0xd1, 0x3c, + 0x58, 0x4f, 0x9f, 0xf0, 0x27, 0xb, 0x1e, 0x4b, 0x67, 0xd3, 0xa6, 0x33, + 0x73, 0x1c, 0x89, 0xa7, 0xbe, 0xba, 0xe9, 0xd9, 0x62, 0xd0, 0x52, 0xeb, + 0xf8, 0x84, 0xcb, 0xe2, 0x92, 0xd3, 0x1d, 0x3, 0xc1, 0x4f, 0x8d, 0xed, + 0x1b, 0xd9, 0xfc, 0xee, 0xbb, 0x10, 0x37, 0xcd, 0xf5, 0x46, 0xd9, 0x37, + 0xdc, 0xf2, 0xf7, 0xad, 0xe2, 0x80, 0x98, 0x65, 0xe, 0xd6, 0x79, 0xd5, + 0xb4, 0x8d, 0x96, 0x39, 0x89, 0x90, 0x71, 0xc, 0x14, 0xc2, 0x8d, 0xa1, + 0x7d, 0xff, 0xbd, 0x48, 0x37, 0xfb, 0x46, 0xdf, 0x1f, 0x32, 0x7b, 0x67, + 0x4f, 0x1f, 0x27, 0x6d, 0x32, 0xa9, 0xb3, 0x5f, 0x66, 0x6b, 0x96, 0x91, + 0x9, 0x9, 0x57, 0x7a, 0xaf, 0xc8, 0xb2, 0xb7, 0x3, 0x23, 0x56, 0x15, + 0xfd, 0x64, 0x97, 0x8a, 0x3e, 0x54, 0xa2, 0xfa, 0x18, 0xf4, 0xac, 0xbc, + 0x28, 0x57, 0x54, 0x27, 0x40, 0xe1, 0x3e, 0x96, 0xe8, 0xa3, 0xf9, 0xc5, + 0xa9, 0x9e, 0x36, 0x27, 0xc, 0x6a, 0xb4, 0xa4, 0x31, 0xe5, 0x5c, 0x68, + 0xf6, 0x98, 0xf2, 0xb2, 0x99, 0x11, 0x2a, 0x34, 0x71, 0x14, 0x42, 0xe4, + 0x96, 0xff, 0x34, 0xed, 0xc5, 0xd5, 0x42, 0x58, 0x2d, 0x12, 0xda, 0xf, + 0x98, 0x2a, 0x2c, 0x9e, 0x61, 0x99, 0xbc, 0xe, 0x1f, 0xd8, 0x1b, 0xa3, + 0x9c, 0xad, 0x83, 0x3c, 0xe3, 0xf5, 0xfe, 0xd6, 0x2a, 0x8c, 0xc5, 0x4e, + 0x1f, 0xf, 0xe9, 0xbf, 0x99, 0x5a, 0x66, 0x42, 0x68, 0xb3, 0xac, 0x1f, + 0x77, 0x65, 0x97, 0x64, 0x80, 0xcd, 0xf7, 0x23, 0xb, 0x8b, 0x55, 0xe6, + 0xd, 0x8b, 0x51, 0xdf, 0x41, 0xb3, 0x29, 0x8d, 0x58, 0xca, 0x93, 0xb4, + 0x52, 0x4e, 0xd3, 0x63, 0xef, 0xbc, 0x7c, 0xb9, 0xd7, 0x2d, 0x51, 0x9b, + 0x31, 0x25, 0x2c, 0xa0, 0xe3, 0x13, 0xa8, 0xac, 0x95, 0x5b, 0x95, 0xfa, + 0x90, 0x95, 0x79, 0xa0, 0xb3, 0xe9, 0xe7, 0xe7, 0x85, 0x91, 0x5c, 0x59, + 0x3d, 0xbc, 0x14, 0x12, 0xae, 0xbc, 0xea, 0xd0, 0xe, 0x5a, 0x3f, 0x28, + 0x18, 0x73, 0xe4, 0x8c, 0x63, 0x84, 0x13, 0x51, 0x6c, 0xa5, 0x73, 0x5a, + 0xea, 0xa0, 0xcd, 0x2e, 0xac, 0x8a, 0xc7, 0xe9, 0x72, 0x70, 0x8a, 0x8c, + 0x63, 0x10, 0x14, 0x96, 0x2f, 0x70, 0x44, 0x75, 0x70, 0x73, 0xe9, 0x3f, + 0x7b, 0xb6, 0x86, 0xf3, 0xfe, 0x67, 0x57, 0xd8, 0x3d, 0x39, 0xd5, 0xf6, + 0xd6, 0x37, 0x8, 0x77, 0x45, 0x2e, 0xa3, 0x4c, 0xbb, 0x90, 0x50, 0x1, + 0xc5, 0xef, 0x1, 0xd3, 0x88, 0x8f, 0x9b, 0x2a, 0x0, 0x65, 0x30, 0xec, + 0x6c, 0x57, 0x9d, 0x19, 0x33, 0x9, 0x2c, 0xd0, 0xde, 0x42, 0x30, 0x6c, + 0x5c, 0x75, 0xf4, 0x3b, 0x76, 0x52, 0x8f, 0xc3, 0xdc, 0x3d, 0xd3, 0x44, + 0x44, 0xd4, 0xeb, 0xf0, 0x6b, 0x70, 0x1b, 0x23, 0x1a, 0xc5, 0xa8, 0xd5, + 0xb9, 0xc, 0xba, 0xfe, 0x18, 0x11, 0xaf, 0x58, 0x43, 0xf4, 0xb3, 0xfb, + 0x18, 0xa0, 0x70, 0x7b, 0x16, 0x79, 0xce, 0x1, 0x2b, 0xae, 0x27, 0x58, + 0x40, 0xd0, 0xda, 0x7e, 0xbe, 0xb3, 0x91, 0x7d, 0xe3, 0xaa, 0x92, 0x92, + 0xc4, 0x58, 0x5b, 0x4b, 0x7b, 0x10, 0x40, 0x2d, 0xb5, 0xc4, 0x2c, 0xed, + 0x62, 0x30, 0xd7, 0x17, 0x6a, 0xaa, 0xd7, 0xf7, 0x85, 0xc7, 0xbe, 0xac, + 0x9e, 0x65, 0x6f, 0xde, 0xd1, 0x25, 0xdc, 0x1f, 0x0, 0x43, 0xe2, 0xe3, + 0x25, 0x22, 0xaa, 0xec, 0xbd, 0x83, 0x1, 0x7c, 0xef, 0x69, 0x81, 0xf9, + 0xd, 0xa9, 0xa0, 0x8b, 0x1a, 0x98, 0xba, 0xf6, 0xa6, 0x1, 0x3a, 0x70, + 0xaa, 0x7b, 0x83, 0x21, 0x87, 0xd2, 0x1d, 0x79, 0x12, 0xd6, 0xe8, 0x54, + 0x63, 0xff, 0xd5, 0xe0, 0x98, 0x61, 0x39, 0xd6, 0x7a, 0xbb, 0xf1, 0x74, + 0x74, 0x27, 0x10, 0xd1, 0x2a, 0x10, 0xe4, 0xeb, 0x6e, 0x2d, 0x50, 0x66, + 0x1f, 0xf9, 0xe6, 0x2a, 0x3e, 0x6a, 0x71, 0x33, 0xa7, 0x80, 0xda, 0xee, + 0xbb, 0x62, 0xc5, 0xa9, 0xd0, 0xd1, 0xd4, 0x8, 0x60, 0xe3, 0xa0, 0x35, + 0xac, 0xe2, 0x76, 0x25, 0xdc, 0x6a, 0x5a, 0x71, 0xab, 0x6f, 0x42, 0xac, + 0x7e, 0xb1, 0xe5, 0xee, 0xc7, 0x74, 0x90, 0x9c, 0x82, 0x6f, 0x39, 0x53, + 0x25, 0x77, 0xea, 0x24, 0x18, 0x1, 0x7d, 0x8a, 0xb4, 0x74, 0xff, 0xd9, + 0xac, 0x24, 0xee, 0x3c, 0x7c, 0x9a, 0xb7, 0x5a, 0xbf, 0xcb, 0xc7, 0x20, + 0xb6, 0xd9, 0xb0, 0x44, 0xfa, 0xe3, 0xe6, 0x33, 0xf5, 0xf6, 0xd6, 0xe5, + 0xda, 0x21, 0xe7, 0x8, 0x36, 0x7d, 0x33, 0x66, 0x3e, 0x8e, 0x0, 0x10, + 0xd, 0x46, 0x8d, 0x36, 0x90, 0x54, 0x8d, 0x72, 0x2c, 0x58, 0x73, 0xc9, + 0x81, 0x90, 0x6a, 0x25, 0xaa, 0x1d, 0x97, 0xea, 0xb9, 0xaf, 0xac, 0x99, + 0xd8, 0x43, 0x16, 0xbd, 0xaf, 0xd0, 0xbf, 0x2f, 0x3f, 0xa0, 0xcd, 0x88, + 0x8, 0x1c, 0xdf, 0x6, 0x75, 0x3a, 0x83, 0x4d, 0x78, 0x99, 0x30, 0xe, + 0x89, 0x7a, 0x91, 0xe, 0x85, 0xf0, 0x95, 0xf9, 0x5c, 0xb9, 0x99, 0x62, + 0x7f, 0xf7, 0x2a, 0x99, 0x8f, 0x30, 0x47, 0x6, 0x6, 0x94, 0x22, 0x70, + 0x0, 0xa6, 0xcf, 0x5e, 0xcf, 0x5a, 0x9, 0xc8, 0x6f, 0x33, 0x8e, 0x90, + 0xb7, 0x7d, 0x9a, 0xe, 0x9e, 0x98, 0xda, 0x62, 0x11, 0x69, 0xa2, 0x9f, + 0x9b, 0x29, 0x1, 0x55, 0xd8, 0x1b, 0x2b, 0x8f, 0xb, 0x68, 0x80, 0xd7, + 0x4e, 0x64, 0x98, 0x50, 0x2d, 0x49, 0x39, 0x13, 0x51, 0xc0, 0x8a, 0x71, + 0xbb, 0x52, 0xbc, 0xb6, 0x36, 0x1b, 0x8e, 0x8e, 0x75, 0x51, 0x8c, 0x35, + 0xe5, 0xa1, 0xd2, 0xa4, 0x6f, 0x53, 0x8c, 0x7a, 0xda, 0x0, 0xe8, 0xe6, + 0xf8, 0x25, 0x42, 0x8e, 0x40, 0x6d, 0x2, 0xcb, 0x71, 0x43, 0x70, 0x9d, + 0xd5, 0xc8, 0x84, 0xb, 0xb8, 0x31, 0xf7, 0x1f, 0x1b, 0x37, 0xb7, 0xea, + 0xd7, 0x48, 0x3a, 0xb9, 0xd9, 0x0, 0xb9, 0x6e, 0x28, 0xf1, 0xc6, 0x1b, + 0xf0, 0xdb, 0x7b, 0x6b, 0xbb, 0x47, 0x5c, 0x1e, 0x9f, 0xd2, 0x49, 0x4, + 0x71, 0xf7, 0x42, 0xfc, 0xe2, 0xf9, 0x80, 0x10, 0x65, 0xfe, 0xf0, 0x14, + 0xcd, 0x5d, 0x26, 0x5d, 0x36, 0x8, 0xe0, 0x12, 0x9c, 0x23, 0xd4, 0x84, + 0xa2, 0xf1, 0xff, 0x8c, 0x94, 0x18, 0x8c, 0x83, 0xaf, 0xaa, 0x37, 0x8b, + 0xfd, 0x81, 0x93, 0xb5, 0xf3, 0xc1, 0x3, 0x54, 0x3b, 0x44, 0x3b, 0x9f, + 0xd0, 0x14, 0x86, 0x2e, 0x29, 0xe3, 0xfc, 0xb4, 0xe7, 0x4a, 0x30, 0xca, + 0x15, 0xb9, 0xa, 0xbe, 0xf7, 0xb3, 0xb6, 0x21, 0x49, 0xd6, 0x3, 0xbb, + 0x1b, 0xa5, 0x27, 0xd9, 0x4b, 0x1b, 0xfd, 0x84, 0x25, 0x4f, 0xc0, 0xb3, + 0x87, 0x96, 0x45, 0xd0, 0x71, 0x97, 0x91, 0xaf, 0x22, 0xad, 0x53, 0x93, + 0xe4, 0xea, 0xcc, 0xf0, 0x10, 0x52, 0x53, 0x86, 0xe1, 0xff, 0x56, 0x13, + 0xe5, 0xec, 0x5c, 0x78, 0xb5, 0xbb, 0x35, 0x4f, 0xea, 0x1a, 0x2d, 0xc1, + 0xf0, 0x32, 0xa1, 0xd9, 0xd, 0xa1, 0xd4, 0x55, 0xb4, 0x55, 0x9f, 0xac, + 0xd, 0x89, 0x25, 0x1d, 0x93, 0x14, 0x83, 0xb4, 0x4f, 0x6c, 0x72, 0xb5, + 0xa5, 0x89, 0xc0, 0x17, 0xc, 0x19, 0x97, 0x55, 0x6e, 0x23, 0x2f, 0x83, + 0x5e, 0x36, 0xf8, 0x35, 0xe3, 0x8d, 0x5a, 0xb5, 0x11, 0xb0, 0x5e, 0xc, + 0x4f, 0x2b, 0xf9, 0x5a, 0xf6, 0x30, 0xce, 0x41, 0x78, 0x2a, 0x5b, 0x61, + 0xa9, 0x70, 0x19, 0x7e, 0x29, 0xd9, 0x73, 0x8b, 0xa2, 0xef, 0xdd, 0xde, + 0x45, 0xb0, 0xf5, 0xbb, 0xd, 0x6c, 0x90, 0x9e, 0x51, 0x1f, 0x19, 0x1d, + 0xa1, 0xe3, 0xaf, 0xff, 0x27, 0x5b, 0x63, 0xb, 0x0, 0xbe, 0x42, 0x55, + 0xc0, 0x17, 0xf9, 0x42, 0x23, 0x8, 0x6, 0x7f, 0x62, 0x2a, 0x76, 0x22, + 0x70, 0x96, 0x28, 0x1b, 0x80, 0x91, 0xf5, 0x65, 0x9c, 0x50, 0x7f, 0xf9, + 0x4c, 0x63, 0x8a, 0xfe, 0xbd, 0xdf, 0xad, 0x93, 0xa7, 0x54, 0x82, 0x11, + 0xf5, 0x6f, 0x77, 0x11, 0xec, 0x36, 0x9f, 0xa, 0xac, 0xa4, 0x9c, 0x4c, + 0x4b, 0x7d, 0x95, 0x6, 0x2b, 0xf7, 0xe2, 0xb9, 0xff, 0xf2, 0x8b, 0xf6, + 0xad, 0xdd, 0x91, 0x9a, 0x99, 0x85, 0x81, 0xd0, 0x12, 0x40, 0x64, 0xf2, + 0x7f, 0x84, 0xc5, 0xc6, 0xd6, 0xc2, 0xaf, 0x1a, 0xdb, 0x28, 0x58, 0x9b, + 0xc9, 0x81, 0x7e, 0x29, 0x60, 0xc2, 0x2e, 0xa3, 0xdb, 0xe4, 0x0, 0xbf, + 0x83, 0xbd, 0xf0, 0xb4, 0xac, 0x81, 0x32, 0xb6, 0xe0, 0x82, 0xe2, 0xa4, + 0x14, 0x9e, 0x1, 0xe4, 0x33, 0x1, 0xe7, 0x9a, 0x7c, 0x2c, 0x1e, 0xa8, + 0xb, 0x95, 0x9, 0x96, 0xd7, 0xe8, 0xc4, 0x77, 0xe3, 0x3, 0x5, 0x4b, + 0x9a, 0x1d, 0x61, 0x42, 0xa6, 0x84, 0xae, 0x46, 0x98, 0x79, 0x46, 0xa7, + 0xc, 0x7b, 0x35, 0xda, 0xbb, 0x4b, 0xaa, 0xfd, 0xcb, 0x7d, 0xc7, 0x4c, + 0x9d, 0x4, 0x9d, 0xd5, 0x22, 0xec, 0xcc, 0xc2, 0xd8, 0x67, 0xd4, 0xee, + 0xb8, 0xc1, 0x6d, 0xb5, 0xe6, 0x5a, 0xa3, 0xfc, 0x4c, 0x75, 0xc3, 0xf7, + 0x5a, 0xc2, 0x47, 0x6d, 0x7c, 0xd5, 0x58, 0xa4, 0x6c, 0x89, 0xb4, 0xcc, + 0x39, 0x58, 0x6e, 0xc0, 0x17, 0x3d, 0x50, 0xaa, 0x23, 0xac, 0x95, 0xbc, + 0x4c, 0x2d, 0xfe, 0x87, 0x1e, 0x88, 0xde, 0xb1, 0xb1, 0x2c, 0xc2, 0x90, + 0x99, 0xe8, 0x1b, 0x11, 0x36, 0x66, 0x37, 0x87, 0x46, 0x22, 0xe8, 0x67, + 0xf6, 0xb5, 0x40, 0xc8, 0x3f, 0x13, 0xf3, 0x83, 0xb3, 0x74, 0x7a, 0x43, + 0x1, 0x73, 0xd3, 0xce, 0x2d, 0x75, 0x10, 0xb9, 0xe8, 0x5d, 0xe5, 0xca, + 0x36, 0x73, 0xa9, 0x71, 0xe0, 0x8, 0x7c, 0x4d, 0xdc, 0xda, 0xa2, 0x87, + 0xad, 0x66, 0x1a, 0xf, 0x5, 0x21, 0x3f, 0xaf, 0xb7, 0x98, 0x2b, 0x65, + 0xec, 0xce, 0xbf, 0x2d, 0xf, 0xe0, 0xa6, 0xfd, 0xf9, 0xb3, 0xf6, 0xe5, + 0x9b, 0xc, 0x2d, 0xb4, 0x5a, 0x95, 0x93, 0xd7, 0x1d, 0x78, 0x95, 0x80, + 0x92, 0xde, 0xb1, 0xb0, 0xb0, 0x59, 0x2, 0xf5, 0xe8, 0xbf, 0x6f, 0xdb, + 0xe3, 0xe0, 0x36, 0x2b, 0xea, 0x4c, 0xe4, 0xe8, 0x19, 0xc7, 0x46, 0xf0, + 0x76, 0x6d, 0x10, 0xbb, 0xbb, 0xdb, 0x55, 0xf8, 0xed, 0x40, 0x6d, 0x25, + 0xf1, 0x8b, 0xb1, 0xfd, 0xe0, 0x70, 0x6b, 0xa2, 0x42, 0x46, 0x51, 0x3d, + 0x60, 0x4c, 0x7c, 0x55, 0x45, 0x76, 0x53, 0x86, 0x4c, 0x70, 0x13, 0xb7, + 0x22, 0xb3, 0xff, 0xa6, 0x26, 0xa8, 0x12, 0x81, 0x7f, 0xce, 0x2b, 0xd5, + 0x4f, 0xf1, 0xef, 0xe, 0xc8, 0xa9, 0xe7, 0x6, 0xd9, 0x9, 0x22, 0xfe, + 0xdd, 0xb6, 0xd1, 0xe4, 0x7a, 0xcb, 0x45, 0xa5, 0x37, 0x6c, 0x7e, 0xef, + 0x16, 0xe9, 0x60, 0xf4, 0x22, 0x9, 0x7d, 0x8a, 0x23, 0xb3, 0x1e, 0x5f, + 0x37, 0x47, 0x3e, 0xcd, 0xdd, 0xe2, 0x26, 0x1b, 0xb8, 0xf, 0x5c, 0x64, + 0x7a, 0xd9, 0x4d, 0xa4, 0x92, 0xa1, 0x42, 0xa5, 0x1b, 0x83, 0xf6, 0xc6, + 0xed, 0x5a, 0xa5, 0xa, 0x18, 0x9c, 0x29, 0xf4, 0xf3, 0xe0, 0x41, 0x98, + 0xbd, 0xd0, 0xb, 0x36, 0x5c, 0x76, 0x9b, 0x73, 0x2b, 0x36, 0xd, 0xa1, + 0x97, 0x9a, 0x1d, 0xfd, 0x4b, 0x4e, 0x26, 0x9c, 0xc9, 0xd0, 0xd6, 0x7a, + 0x9c, 0xb1, 0xbb, 0x6e, 0x13, 0x81, 0x30, 0x76, 0x47, 0xc1, 0x15, 0x5e, + 0xa, 0xe9, 0xf0, 0x5c, 0xae, 0x94, 0xb6, 0x6f, 0x9a, 0x16, 0xa, 0xa2, + 0x84, 0x79, 0x31, 0xa9, 0x53, 0x63, 0xc9, 0xb5, 0x52, 0x54, 0x1c, 0x15, + 0x3f, 0x97, 0xb4, 0xe3, 0x21, 0x3, 0xc5, 0x6e, 0x91, 0x3b, 0xf3, 0x50, + 0xe1, 0x1e, 0x80, 0x9a, 0xad, 0x8a, 0xac, 0xb7, 0x3f, 0xd9, 0xfa, 0x39, + 0xb7, 0x7, 0x93, 0xe7, 0xd9, 0xee, 0x2e, 0xf2, 0xe8, 0x2c, 0xc5, 0x58, + 0x36, 0xf1, 0xd1, 0x5e, 0xf7, 0xa5, 0xf2, 0xce, 0xf3, 0xd8, 0xf7, 0x89, + 0x22, 0xe8, 0xfb, 0xbb, 0x17, 0xca, 0xb3, 0xec, 0x8d, 0xc, 0x24, 0x3f, + 0xa2, 0x31, 0x60, 0x76, 0xf7, 0xb2, 0xdb, 0xc6, 0x65, 0x6c, 0xaa, 0x71, + 0xdd, 0x9c, 0xee, 0x65, 0xd3, 0x4b, 0x91, 0x83, 0xf1, 0xb8, 0x8, 0xb2, + 0x10, 0x63, 0xba, 0xbd, 0xfe, 0x19, 0x4d, 0xe6, 0xb7, 0xdf, 0x1c, 0xd6, + 0x2c, 0x4a, 0x3c, 0x1a, 0x71, 0x43, 0xa8, 0xdf, 0x54, 0xea, 0xe7, 0xe, + 0xc5, 0x18, 0xae, 0x85, 0x15, 0x17, 0x5c, 0x90, 0x72, 0xb9, 0x49, 0x98, + 0xe2, 0xa5, 0xd5, 0xad, 0x1b, 0x97, 0x54, 0xcf, 0x33, 0xc9, 0x6b, 0xa6, + 0x43, 0xc9, 0xbe, 0xf6, 0xc5, 0xb1, 0x26, 0x40, 0xab, 0xfe, 0x5e, 0xb8, + 0x47, 0x36, 0x8c, 0x85, 0xa7, 0x29, 0x36, 0xb3, 0xc, 0x22, 0xa7, 0xb1, + 0x23, 0x7c, 0xcb, 0x8a, 0xe2, 0x11, 0x5c, 0x3e, 0x88, 0xbe, 0x44, 0x1e, + 0x9b, 0xb7, 0x8f, 0x9b, 0x22, 0x48, 0x99, 0xd7, 0xbf, 0xc0, 0xd7, 0xae, + 0xfa, 0x36, 0x19, 0xa8, 0xc2, 0x32, 0x69, 0x87, 0x8f, 0xc6, 0xee, 0xa1, + 0x40, 0xe1, 0x1e, 0xf9, 0xf7, 0x8f, 0xb7, 0xb6, 0x97, 0xed, 0xa6, 0x5a, + 0x69, 0x25, 0xc3, 0x95, 0x98, 0xb3, 0x6b, 0x70, 0x5c, 0xab, 0xfd, 0x22, + 0x44, 0xbe, 0xd8, 0xe5, 0x8a, 0xde, 0x76, 0x75, 0x50, 0x4a, 0x1a, 0x13, + 0x55, 0xd0, 0x24, 0x77, 0xc2, 0x21, 0xb8, 0xe4, 0xe5, 0x1a, 0x9e, 0xed, + 0x67, 0x2c, 0xa6, 0x7e, 0xe5, 0xf, 0x4c, 0x62, 0xd8, 0xd5, 0x4c, 0xa1, + 0x84, 0x3e, 0x64, 0x74, 0x51, 0xd6, 0x74, 0x78, 0xaf, 0x62, 0xa7, 0xbb, + 0xcf, 0x37, 0x19, 0x64, 0x1f, 0xe7, 0x96, 0x55, 0x99, 0x41, 0xab, 0xc9, + 0x9b, 0x2b, 0x4e, 0x72, 0xb1, 0x33, 0x7d, 0xa4, 0xa1, 0xda, 0xc5, 0xcd, + 0x26, 0xbf, 0xa9, 0x98, 0x9c, 0x84, 0x63, 0xc4, 0x40, 0xd, 0x1f, 0x2a, + 0xc1, 0xa4, 0x2f, 0xa3, 0x31, 0x7d, 0x6a, 0x11, 0x90, 0x21, 0xf3, 0x77, + 0xa2, 0x34, 0xbe, 0x3, 0xcd, 0xe, 0xd8, 0x43, 0x2b, 0xb9, 0xb6, 0xce, + 0xb4, 0xf3, 0xa4, 0x1c, 0x2, 0xa8, 0x56, 0x1f, 0x41, 0x33, 0x12, 0x51, + 0x26, 0xee, 0x84, 0x21, 0x87, 0x1b, 0xed, 0x7, 0x20, 0x80, 0x6a, 0x3b, + 0xb4, 0x40, 0x77, 0x9f, 0x1e, 0x3d, 0xc5, 0x39, 0xe6, 0xc9, 0xc3, 0xbd, + 0xd0, 0x9, 0x8f, 0x6, 0xde, 0xd2, 0x41, 0x70, 0x32, 0xb1, 0xaf, 0xf4, + 0xd4, 0x3f, 0x4, 0xf0, 0xb3, 0x95, 0xe0, 0xd9, 0x78, 0x5f, 0x31, 0x4, + 0x3f, 0xcf, 0x9a, 0xe3, 0x93, 0xbd, 0x29, 0xa9, 0x27, 0x77, 0x27, 0x13, + 0x64, 0xd9, 0x90, 0xf4, 0x24, 0x5a, 0x2f, 0x5e, 0x36, 0x67, 0xa, 0x66, + 0x97, 0x3b, 0xbc, 0x12, 0xdf, 0xd4, 0xbc, 0x65, 0x3d, 0x43, 0x73, 0x27, + 0x3d, 0xf2, 0xa1, 0x72, 0x4c, 0x49, 0x8c, 0xc2, 0xd4, 0x13, 0x15, 0xee, + 0x1b, 0xfd, 0xa6, 0xa8, 0x22, 0x4b, 0x2b, 0x80, 0x7e, 0x81, 0x52, 0x5f, + 0x89, 0x3c, 0xd2, 0xe2, 0xc3, 0x7c, 0x22, 0x9c, 0x95, 0xac, 0x4f, 0x7a, + 0xe5, 0x77, 0x6d, 0x9, 0xde, 0x7d, 0x2a, 0xd7, 0x91, 0x75, 0x11, 0x61, + 0x1e, 0x88, 0xa9, 0xa4, 0x40, 0xda, 0x7a, 0x7f, 0xc5, 0x9c, 0x13, 0xbf, + 0x50, 0x52, 0xbc, 0xb6, 0x1, 0xcb, 0x7e, 0xa9, 0xaf, 0xcf, 0xd0, 0x49, + 0xc8, 0x91, 0x5d, 0xbd, 0xd9, 0x41, 0xa5, 0xc4, 0xc, 0x13, 0x79, 0x1e, + 0xaf, 0xb0, 0x7c, 0xa7, 0xea, 0x5c, 0x10, 0xd3, 0xa7, 0x82, 0x47, 0xfc, + 0x5, 0xb0, 0xe7, 0x5d, 0x7c, 0xf2, 0xf6, 0xc1, 0x3e, 0xc4, 0x81, 0x33, + 0x2e, 0x98, 0x8f, 0xc8, 0x2b, 0xba, 0x71, 0x13, 0x39, 0xa2, 0x2a, 0xc8, + 0x7d, 0xf8, 0xe0, 0x4b, 0x5f, 0x1d, 0x9a, 0x4e, 0x71, 0xb3, 0x56, 0xf9, + 0x77, 0x63, 0x37, 0xca, 0x71, 0xa9, 0x71, 0xf3, 0x17, 0xdc, 0x49, 0xa2, + 0x5e, 0x80, 0xd6, 0x17, 0xa5, 0x13, 0xa5, 0xf4, 0x91, 0xef, 0x65, 0xf2, + 0x69, 0x85, 0x6d, 0x9f, 0x1d, 0xf8, 0x52, 0x57, 0xf9, 0xcb, 0xa7, 0x89, + 0x3c, 0x28, 0x19, 0xa3, 0xc4, 0xae, 0xd, 0x21, 0xf4, 0x6b, 0x42, 0xab, + 0x8a, 0xf, 0xfc, 0xa6, 0x7, 0xdc, 0x7c, 0x9f, 0x2c, 0xc0, 0xce, 0x7d, + 0x8e, 0xcd, 0x7f, 0x75, 0xab, 0xf9, 0xac, 0xcb, 0x59, 0x1c, 0x64, 0x6b, + 0x16, 0x64, 0x3d, 0x89, 0x8b, 0x2b, 0x5a, 0x93, 0xae, 0x95, 0x53, 0xcb, + 0x4c, 0x7c, 0xa3, 0x5e, 0xda, 0xee, 0x69, 0xdf, 0xc1, 0x82, 0x7d, 0x3b, + 0x30, 0x3c, 0x8b, 0xeb, 0x1f, 0xa0, 0xff, 0x95, 0x60, 0x70, 0x52, 0x15, + 0x3f, 0x58, 0xd7, 0xba, 0xc1, 0xe3, 0x72, 0x24, 0x5d, 0xf0, 0x84, 0xdb, + 0x78, 0xdc, 0x40, 0xb9, 0x6c, 0x68, 0xed, 0x5e, 0x7b, 0x2, 0x27, 0xae, + 0x59, 0xce, 0xab, 0x4b, 0xa4, 0xe4, 0xce, 0xa, 0x69, 0xb7, 0x5b, 0xad, + 0xcb, 0x14, 0xbb, 0x25, 0x88, 0xe7, 0xea, 0x89, 0xd7, 0x35, 0x84, 0x8f, + 0x6c, 0x33, 0x75, 0xab, 0x64, 0x94, 0x51, 0x22, 0x15, 0xe2, 0x57, 0xab, + 0xff, 0xfa, 0x4e, 0x0, 0x7c, 0xb0, 0x29, 0xa7, 0x6, 0xa, 0x3a, 0xa8, + 0x4d, 0xaf, 0x7c, 0x5c, 0x7a, 0xc6, 0x48, 0xb4, 0xb8, 0xda, 0x3a, 0x6, + 0x9b, 0xf, 0xae, 0xf5, 0x85, 0x3a, 0xc2, 0xa0, 0x9f, 0x21, 0xda, 0x5d, + 0x3b, 0xae, 0xc7, 0x30, 0x81, 0xd9, 0x40, 0x70, 0xe4, 0xb3, 0xc4, 0xe2, + 0xa3, 0x1c, 0xf2, 0xd0, 0x60, 0xf4, 0x68, 0x1, 0xac, 0xa1, 0x84, 0x99, + 0x19, 0xd6, 0x9e, 0x52, 0x83, 0xd, 0x24, 0xd0, 0xc9, 0x61, 0xaf, 0x51, + 0xfa, 0xf3, 0xbb, 0xd, 0xb1, 0x5e, 0xba, 0xb8, 0x39, 0x9d, 0x15, 0xa, + 0xa3, 0x78, 0xa4, 0xb9, 0x19, 0x4f, 0xce, 0x45, 0xe0, 0x36, 0x4d, 0x3c, + 0x43, 0x34, 0xac, 0x69, 0xef, 0x7d, 0xf3, 0x31, 0xb8, 0x4d, 0x9d, 0x94, + 0xc6, 0xad, 0xb5, 0xda, 0x90, 0x26, 0xb9, 0x39, 0x9e, 0xb, 0x90, 0x55, + 0x77, 0xc9, 0xca, 0xcd, 0x77, 0x18, 0x81, 0xcc, 0x40, 0x23, 0x0, 0xf1, + 0x6f, 0x7a, 0x3d, 0x96, 0xf0, 0x9, 0x93, 0x4e, 0xe3, 0xd6, 0x2c, 0xe, + 0x79, 0x51, 0x8e, 0x6a, 0x9, 0x1, 0x32, 0x51, 0xfa, 0x40, 0x9a, 0x93, + 0x77, 0x27, 0xf, 0x54, 0xb, 0xda, 0xae, 0x47, 0x4a, 0xc3, 0x3d, 0xcd, + 0x88, 0x22, 0x12, 0x63, 0xee, 0x3b, 0x9f, 0x6f, 0xcc, 0xc9, 0x1, 0x4b, + 0xf0, 0x30, 0x6a, 0x99, 0x27, 0x20, 0xb, 0x9b, 0x1f, 0x83, 0xbc, 0x83, + 0xf, 0x35, 0x7c, 0xd, 0x61, 0x5c, 0x90, 0x43, 0x98, 0x8d, 0x24, 0xfd, + 0x91, 0xcc, 0x3b, 0x10, 0x43, 0x52, 0x41, 0x70, 0xf2, 0x4d, 0x35, 0x13, + 0x1, 0x6c, 0x2b, 0xc6, 0xe8, 0xf1, 0xc1, 0xe5, 0x88, 0x5e, 0xd2, 0x95, + 0x51, 0x10, 0xa2, 0x2, 0x6, 0xb8, 0x3a, 0x33, 0x67, 0x81, 0x4b, 0x1d, + 0xef, 0x74, 0xb5, 0x38, 0x6f, 0xd3, 0x52, 0x1f, 0xf6, 0xc8, 0x10, 0xa8, + 0xe3, 0x7e, 0x19, 0xb, 0x82, 0xb7, 0x50, 0xee, 0xba, 0x48, 0xb8, 0x3, + 0xad, 0x2a, 0x96, 0x22, 0x12, 0x1c, 0x4d, 0x41, 0x93, 0xfc, 0x52, 0xaf, + 0x77, 0x58, 0x88, 0xcc, 0xff, 0xef, 0x4, 0x3c, 0x4f, 0x89, 0xda, 0x61, + 0x84, 0xa1, 0x1f, 0xdb, 0x1b, 0xd6, 0xfd, 0x26, 0x2b, 0x23, 0xf9, 0xc0, + 0xe3, 0xa8, 0x68, 0xf4, 0x4, 0x79, 0x3, 0x78, 0x92, 0xfc, 0x1f, 0x32, + 0xf4, 0x56, 0x9a, 0xa6, 0xfc, 0x2e, 0xe, 0x5a, 0x11, 0x49, 0x6b, 0x8f, + 0x57, 0x59, 0x84, 0xac, 0x41, 0x51, 0xa2, 0x64, 0x93, 0x31, 0xd9, 0x7, + 0x0, 0xfb, 0x32, 0x11, 0xdc, 0x7b, 0xee, 0xd7, 0x38, 0xed, 0xe9, 0xba, + 0x2a, 0x71, 0x2f, 0xec, 0x7a, 0xac, 0xd9, 0xf6, 0xe9, 0xb0, 0xd3, 0x72, + 0x5b, 0x4b, 0xd, 0x7c, 0x2f, 0x33, 0xb8, 0xbb, 0x32, 0x64, 0xcf, 0xcf, + 0x29, 0xf5, 0xf2, 0xc6, 0xeb, 0xe2, 0x75, 0x9a, 0x3b, 0x94, 0x30, 0x99, + 0x14, 0xc, 0xc5, 0x1d, 0xc2, 0x59, 0xdb, 0xbe, 0xe1, 0x7b, 0x84, 0x45, + 0x22, 0x8d, 0x76, 0xe5, 0x10, 0x5d, 0xbb, 0x43, 0xa2, 0x62, 0xa2, 0x95, + 0xdc, 0x3e, 0xbd, 0x90, 0x3f, 0x4a, 0xed, 0x6d, 0x67, 0xe2, 0x75, 0xa, + 0x57, 0xd5, 0x30, 0x55, 0x5a, 0xe8, 0x76, 0x70, 0x99, 0x8d, 0xbd, 0x81, + 0x4d, 0x93, 0x19, 0x9d, 0x53, 0x83, 0xb1, 0xa8, 0x1b, 0x82, 0x75, 0x85, + 0x2d, 0xa0, 0x8e, 0xbd, 0x7d, 0xae, 0x60, 0x8e, 0x8a, 0x36, 0x43, 0xfc, + 0x72, 0xf3, 0x93, 0x83, 0xc0, 0xfa, 0xee, 0x44, 0xf8, 0x4f, 0x37, 0x56, + 0xa4, 0xaf, 0x8f, 0xa4, 0x4, 0x2b, 0xaf, 0x6c, 0xb8, 0x5c, 0x29, 0x37, + 0x4c, 0xd6, 0x81, 0x7c, 0x8b, 0x8c, 0x57, 0x88, 0xf1, 0xf0, 0x15, 0x74, + 0x45, 0x86, 0x2f, 0xab, 0x2b, 0xf0, 0x4b, 0x1a, 0x37, 0x8b, 0x46, 0x63, + 0x2f, 0x2a, 0x85, 0xfb, 0x94, 0x3b, 0x89, 0xa4, 0xd0, 0x48, 0xf2, 0x82, + 0xa6, 0xfc, 0x33, 0xa5, 0x76, 0x78, 0x76, 0x9e, 0xd6, 0x4e, 0x49, 0xd, + 0x86, 0xf7, 0x16, 0x57, 0x2b, 0xe6, 0xc5, 0x38, 0x26, 0xc3, 0x2c, 0xfa, + 0x36, 0xec, 0xef, 0xb9, 0xa0, 0x0, 0x47, 0xa, 0x33, 0x47, 0x9a, 0xc2, + 0xe3, 0xc6, 0x6b, 0x18, 0x21, 0xb, 0x1a, 0x37, 0x19, 0x8b, 0xe0, 0x90, + 0xaf, 0x9d, 0x97, 0x8, 0xf3, 0x69, 0x1a, 0x4f, 0xf, 0x90, 0x1b, 0xad, + 0xf2, 0xc, 0x3a, 0x2, 0x91, 0xae, 0x35, 0xd2, 0x89, 0xf, 0xb3, 0x1c, + 0x7a, 0xce, 0xa2, 0xa7, 0xcc, 0xa8, 0x10, 0x6a, 0x57, 0xef, 0x6a, 0xa2, + 0x9, 0xbb, 0x24, 0x69, 0x20, 0x34, 0xa2, 0xbd, 0xd5, 0x8c, 0x9d, 0x65, + 0xba, 0x7f, 0x1b, 0x3d, 0xbd, 0xf4, 0xca, 0x57, 0xa4, 0xe1, 0x3c, 0x77, + 0xc1, 0x96, 0x7f, 0x5c, 0xdb, 0xe8, 0x48, 0xda, 0x9c, 0xa4, 0x47, 0x50, + 0x59, 0xdd, 0x7b, 0x17, 0xef, 0x86, 0xf1, 0xaa, 0x66, 0xa3, 0xd8, 0x37, + 0xb5, 0x65, 0xc6, 0x38, 0x87, 0x75, 0x35, 0xd5, 0xe9, 0xb8, 0x96, 0x84, + 0x55, 0xf7, 0x66, 0x52, 0x86, 0x9c, 0x50, 0x42, 0x3d, 0x21, 0x3, 0xdf, + 0x19, 0x40, 0x9d, 0x36, 0xa6, 0xb1, 0x5e, 0xd6, 0xa2, 0xee, 0x1f, 0x16, + 0xa5, 0x72, 0x8, 0xb0, 0xfb, 0x58, 0x5a, 0xd8, 0xfe, 0xad, 0x28, 0x39, + 0x2c, 0xe9, 0x58, 0xa0, 0xc6, 0x64, 0xda, 0x1b, 0x8a, 0x23, 0xbd, 0xed, + 0x83, 0x19, 0x9b, 0xaf, 0x54, 0x1c, 0x11, 0x24, 0xf6, 0xc7, 0x81, 0xcf, + 0x8f, 0xd, 0x38, 0x29, 0xdd, 0x57, 0xf2, 0x8d, 0x6a, 0x9f, 0x54, 0xcd, + 0xec, 0xf2, 0xd3, 0x57, 0xbe, 0xad, 0x3f, 0xd3, 0xd1, 0x72, 0x33, 0x4d, + 0xf, 0xa6, 0xf7, 0x32, 0xab, 0x46, 0x5f, 0x58, 0x24, 0x43, 0xef, 0x1, + 0x5a, 0xe4, 0x4e, 0x31, 0xd3, 0xcd, 0xad, 0xda, 0x81, 0x4f, 0xfa, 0xfa, + 0x8a, 0xb0, 0xd7, 0xbe, 0xaa, 0x24, 0x76, 0xbd, 0xb, 0xf2, 0xf3, 0xad, + 0x9c, 0xa7, 0xd2, 0x8e, 0xa, 0xa7, 0x27, 0x61, 0x47, 0xab, 0x39, 0xb, + 0xdb, 0xb, 0x4d, 0xbe, 0x85, 0x4, 0x77, 0xde, 0xfc, 0x86, 0xe9, 0xb, + 0xfc, 0x66, 0xd, 0xf7, 0x48, 0x3c, 0x13, 0x85, 0x62, 0x72, 0xdc, 0xb2, + 0x4d, 0x59, 0xab, 0xf, 0xbc, 0x14, 0x2f, 0x7f, 0x87, 0x16, 0xdd, 0xb7, + 0xf7, 0xa7, 0xa3, 0xe, 0xc4, 0x19, 0xbb, 0xae, 0x39, 0xb5, 0x24, 0x5d, + 0x8c, 0xb8, 0x87, 0xc0, 0x1, 0x61, 0xf, 0xb3, 0x6, 0xc1, 0x6b, 0x25, + 0xb8, 0xaf, 0x22, 0xf1, 0x44, 0x11, 0xa3, 0x8b, 0x29, 0x3, 0xcb, 0x10, + 0xe9, 0xd0, 0x3c, 0x7a, 0xb4, 0xb6, 0xb1, 0x1e, 0xb3, 0xb8, 0x52, 0x7f, + 0xf5, 0xa0, 0xa5, 0x46, 0xf0, 0x48, 0x1e, 0x13, 0x71, 0x31, 0xc9, 0x2b, + 0x41, 0x54, 0x4a, 0xcc, 0x5e, 0xa0, 0x5d, 0xe5, 0xb8, 0x94, 0x50, 0x8a, + 0x4f, 0xcd, 0x6c, 0x42, 0xd9, 0x83, 0x19, 0xa4, 0xa0, 0x3f, 0xe2, 0xf7, + 0x8b, 0x41, 0xc5, 0xca, 0xfa, 0xc3, 0x4a, 0xde, 0x74, 0x14, 0xd8, 0xa4, + 0xf3, 0x5e, 0x25, 0xac, 0x8c, 0xa8, 0xf9, 0x20, 0x1d, 0x77, 0x77, 0xe3, + 0xfe, 0xb8, 0x84, 0x8f, 0x70, 0x3c, 0xce, 0xc4, 0x3c, 0xdf, 0xe5, 0x9b, + 0x7b, 0x8b, 0xd, 0xf2, 0xf4, 0xa, 0x93, 0x0, 0x53, 0x33, 0x27, 0x19, + 0x3f, 0x61, 0xa4, 0x5f, 0x8e, 0x19, 0xe1, 0xbb, 0x96, 0x71, 0xd6, 0xb1, + 0x5c, 0xfe, 0x74, 0x4c, 0xdd, 0x5, 0xd2, 0xac, 0xea, 0xd3, 0x3f, 0xc4, + 0x24, 0x7a, 0x2c, 0xdc, 0x3c, 0x9, 0xc, 0x88, 0x3e, 0xd6, 0x6a, 0xdf, + 0x2e, 0xe6, 0x71, 0x9a, 0xb5, 0x79, 0x25, 0xc8, 0xdb, 0x8a, 0xcd, 0x37, + 0x33, 0xc8, 0x34, 0xd4, 0x14, 0x9a, 0x19, 0xbd, 0xb2, 0x59, 0x5d, 0x91, + 0xa8, 0x66, 0xb3, 0x93, 0x18, 0x64, 0xb3, 0xaa, 0xb9, 0x2d, 0xe, 0x3d, + 0x28, 0xca, 0xa3, 0xbd, 0x1f, 0x11, 0x55, 0x3d, 0xd, 0xb9, 0x2e, 0x18, + 0x0, 0x0, 0xb, 0x80, 0xe4, 0x8b, 0xea, 0xc4, 0x11, 0xb7, 0x33, 0xd6, + 0x74, 0x23, 0x35, 0x8c, 0x73, 0xf7, 0xd4, 0x38, 0x17, 0x25, 0xbb, 0x2b, + 0xb8, 0xea, 0x54, 0xf3, 0x93, 0x2b, 0x56, 0x14, 0xb5, 0x80, 0xc5, 0x1c, + 0x9a, 0x10, 0x4c, 0x87, 0xc5, 0x25, 0x94, 0x8e, 0xad, 0x8c, 0x44, 0x6a, + 0x77, 0xfc, 0x55, 0x57, 0xc0, 0xe0, 0x1a, 0xbf, 0x1f, 0x6f, 0x76, 0xd7, + 0x51, 0xd1, 0x20, 0x3f, 0x3, 0x5a, 0xcb, 0x5, 0x3a, 0x3e, 0xa7, 0x9, + 0x7d, 0x1a, 0xf, 0xf8, 0x48, 0x31, 0x75, 0xfb, 0xf2, 0x46, 0xa3, 0x75, + 0x68, 0xcf, 0x49, 0x16, 0x96, 0x71, 0xbb, 0x29, 0xf0, 0x7, 0xe4, 0xdc, + 0x7e, 0x73, 0xc0, 0xc7, 0xe4, 0x3c, 0xbc, 0xad, 0x37, 0x4d, 0x9f, 0x11, + 0xd4, 0xe4, 0x5a, 0xac, 0xcb, 0xe8, 0xd6, 0x6a, 0xaa, 0x5c, 0xc7, 0x84, + 0x9c, 0x40, 0x66, 0xe9, 0x54, 0x7c, 0x9d, 0x10, 0xf2, 0x28, 0xa, 0x77, + 0xcb, 0xbd, 0x57, 0x78, 0x64, 0x2, 0x89, 0x6c, 0x4e, 0x41, 0xb6, 0x8f, + 0x2c, 0x4f, 0x21, 0x31, 0x57, 0xcc, 0xfd, 0xe6, 0xe2, 0xf, 0xfd, 0x85, + 0x6e, 0xcc, 0x30, 0x8b, 0x67, 0xad, 0x4d, 0x3, 0x93, 0x75, 0x4a, 0x71, + 0x99, 0x1a, 0xd0, 0xe8, 0x2b, 0xe9, 0x57, 0x21, 0xdb, 0xf2, 0x1b, 0x73, + 0x21, 0x2, 0x2f, 0x84, 0x48, 0x6c, 0xfe, 0xbe, 0xbe, 0xf1, 0xaa, 0x8b, + 0xa5, 0xe6, 0x51, 0xb, 0xa3, 0x98, 0x4c, 0x6f, 0x56, 0xe, 0x6, 0x61, + 0xa4, 0xd8, 0x5a, 0x9f, 0x42, 0xe, 0x3, 0x3d, 0xbb, 0xf5, 0xed, 0xe5, + 0x9e, 0x62, 0x55, 0x62, 0x74, 0x2b, 0xd0, 0xdd, 0x6c, 0xd3, 0x8c, 0xc1, + 0xc5, 0xc8, 0x1, 0xf, 0xfa, 0x3, 0xde, 0x4e, 0xb1, 0x16, 0xd, 0x79, + 0x20, 0xa8, 0xbc, 0x9f, 0x2a, 0x8d, 0x53, 0xac, 0xb3, 0xa2, 0x48, 0x97, + 0xb0, 0x1a, 0xb3, 0x83, 0xee, 0x19, 0x5, 0xc7, 0x31, 0x3b, 0x47, 0xb9, + 0xa3, 0xce, 0x42, 0x9f, 0xf3, 0x73, 0x42, 0x4f, 0x56, 0xf8, 0xdb, 0x3b, + 0xea, 0x3e, 0x61, 0xdc, 0x6f, 0x76, 0x89, 0xb7, 0x2c, 0x2d, 0x77, 0x51, + 0xf3, 0x4, 0x0, 0xd3, 0xa2, 0x44, 0x5d, 0x4e, 0x47, 0xc7, 0x80, 0x51, + 0x11, 0x56, 0x47, 0xc0, 0x66, 0xf6, 0xa1, 0x7b, 0x28, 0x7e, 0x62, 0x19, + 0x32, 0x41, 0x97, 0x19, 0x7d, 0xca, 0x6c, 0xd1, 0x9f, 0x9a, 0xc6, 0x23, + 0x87, 0x30, 0x1, 0xee, 0x3a, 0xb2, 0x36, 0x61, 0x73, 0xf1, 0x2e, 0xbb, + 0x6f, 0xc9, 0x52, 0x8a, 0x51, 0x11, 0x63, 0x70, 0xc4, 0xff, 0xb8, 0xfd, + 0x45, 0xe1, 0x2f, 0x67, 0xdc, 0x75, 0x34, 0x81, 0x25, 0x63, 0xd8, 0x40, + 0x69, 0x80, 0xc0, 0xc8, 0x7d, 0x69, 0xd3, 0xf1, 0x2b, 0xaf, 0xee, 0x55, + 0x83, 0x6a, 0x87, 0xf6, 0xf1, 0x2c, 0x6, 0x1d, 0x24, 0xb2, 0x8b, 0x70, + 0x73, 0x45, 0x6f, 0x9e, 0x94, 0x12, 0x1d, 0xee, 0xf9, 0xa8, 0x7d, 0x8b, + 0x19, 0xf7, 0x8e, 0xd3, 0x9e, 0xee, 0x81, 0x11, 0x60, 0xc3, 0x6d, 0xf6, + 0xa0, 0x70, 0xe0, 0x73, 0xb1, 0x3c, 0x9b, 0x3b, 0x44, 0x59, 0x8, 0x59, + 0xac, 0xae, 0xfe, 0x43, 0x16, 0x74, 0x1, 0xe, 0x89, 0x9e, 0x11, 0x26, + 0xc6, 0xf7, 0x8, 0xaa, 0xc2, 0x74, 0x7e, 0x13, 0xea, 0xce, 0x8a, 0xb8, + 0x96, 0x7e, 0x30, 0x53, 0x69, 0xc1, 0xec, 0x52, 0x40, 0xc9, 0x95, 0x9a, + 0x31, 0x80, 0xc6, 0xb4, 0x60, 0x79, 0x2, 0xa4, 0x85, 0xad, 0x5f, 0x76, + 0xdc, 0x4f, 0x6d, 0x29, 0x4b, 0x6c, 0xc5, 0x2f, 0xe, 0xc5, 0xa5, 0xe4, + 0x61, 0x8, 0x21, 0x46, 0x19, 0x71, 0x87, 0x1b, 0xf4, 0xbe, 0xe0, 0xaf, + 0x76, 0xb, 0xa2, 0x2e, 0x4c, 0x49, 0x0, 0x68, 0xb2, 0xd5, 0xd8, 0x92, + 0xd8, 0x5e, 0x65, 0x46, 0x7d, 0xb6, 0x16, 0xf6, 0xd6, 0x8b, 0x6d, 0x5d, + 0xd1, 0xa5, 0xfa, 0x3a, 0x38, 0xc1, 0x8b, 0x89, 0xbf, 0x28, 0xff, 0x26, + 0xf5, 0x88, 0xde, 0x89, 0x6b, 0x7b, 0xa6, 0x45, 0x64, 0x43, 0xd, 0xf1, + 0x75, 0x8a, 0x38, 0xc9, 0x65, 0xae, 0xbb, 0xa4, 0x3e, 0xd9, 0x8f, 0x2c, + 0x93, 0xf3, 0x94, 0xcb, 0x14, 0x73, 0xd2, 0x80, 0x19, 0x19, 0xa2, 0x7b, + 0x0, 0xf3, 0x59, 0xb1, 0x18, 0x1e, 0x94, 0x4, 0xf8, 0x21, 0x6e, 0xa8, + 0x94, 0x4c, 0x73, 0xb, 0x85, 0xba, 0x90, 0xb0, 0xbd, 0xcd, 0x91, 0xb8, + 0x79, 0x29, 0xf6, 0xf3, 0x11, 0xcc, 0xcb, 0x9c, 0x7b, 0xd4, 0x5d, 0xae, + 0xfd, 0x22, 0x24, 0x8, 0xc0, 0x56, 0x80, 0xd4, 0x64, 0x26, 0x8e, 0x73, + 0x8b, 0x12, 0xb2, 0x1, 0xce, 0xd1, 0xdd, 0x5d, 0xad, 0xf1, 0x98, 0x5d, + 0x30, 0x72, 0x6c, 0x3a, 0x53, 0xd3, 0x8d, 0x2d, 0x43, 0x7d, 0x9c, 0x91, + 0xe7, 0x0, 0xc0, 0x85, 0xdf, 0x89, 0x8d, 0xe4, 0x6d, 0x8c, 0x50, 0xc2, + 0xd4, 0x4e, 0x4c, 0x85, 0x31, 0x7f, 0xb, 0x6e, 0xac, 0x53, 0x23, 0x65, + 0xd9, 0x56, 0x5c, 0x1f, 0xca, 0x15, 0xd2, 0xec, 0x46, 0x99, 0x5b, 0xc6, + 0xd8, 0x1d, 0x3d, 0x12, 0xf, 0x3c, 0xfe, 0xaf, 0xc5, 0x2, 0x76, 0x57, + 0x1e, 0x4b, 0xd2, 0xae, 0x8f, 0xcc, 0xe0, 0xbc, 0x34, 0x41, 0x36, 0x3c, + 0x1b, 0xb6, 0xa9, 0xf3, 0xb3, 0x31, 0x91, 0xd8, 0x9e, 0xcf, 0x84, 0x8, + 0x83, 0x56, 0x18, 0xe9, 0x2a, 0xd3, 0xfb, 0xeb, 0x87, 0xbb, 0x12, 0xbf, + 0xf9, 0x6, 0x9, 0xdd, 0x5a, 0xd9, 0x32, 0x6a, 0x9, 0xcf, 0x33, 0x7b, + 0x3c, 0xca, 0xf8, 0xc4, 0x4e, 0x33, 0x8d, 0xb6, 0xfb, 0xe7, 0xd, 0x24, + 0xc0, 0x4a, 0x92, 0x25, 0xb, 0x48, 0x9d, 0xe7, 0xf0, 0x32, 0x29, 0x12, + 0x89, 0xb, 0xba, 0x8f, 0x46, 0xae, 0x21, 0x74, 0x98, 0xe9, 0xb4, 0x5a, + 0x74, 0x49, 0x31, 0xa0, 0x94, 0x97, 0xaf, 0xe0, 0x17, 0xbc, 0x3f, 0x21, + 0x2a, 0x4f, 0xe8, 0x21, 0x91, 0x61, 0x57, 0xb8, 0x3e, 0xe6, 0x4a, 0xa6, + 0x88, 0x49, 0xd2, 0x78, 0xbe, 0xd9, 0xc6, 0x87, 0x35, 0x8f, 0x52, 0x53, + 0xfb, 0x9a, 0x12, 0x61, 0xfd, 0xb1, 0xd, 0xe0, 0x1a, 0x6c, 0xda, 0xe1, + 0x44, 0x22, 0x4a, 0x59, 0x12, 0x2, 0x88, 0xf9, 0x41, 0x2d, 0x5b, 0x28, + 0x38, 0xcf, 0x2a, 0x45, 0x5b, 0x32, 0xed, 0xe2, 0x1, 0x1f, 0x7f, 0xde, + 0x5d, 0xbe, 0x74, 0x43, 0x9e, 0x77, 0xba, 0x83, 0xae, 0xda, 0x24, 0x2c, + 0x5e, 0x20, 0x20, 0x2d, 0xfc, 0x5e, 0x47, 0x95, 0xed, 0xb1, 0x18, 0x5, + 0xf5, 0xcd, 0xcd, 0xc6, 0x78, 0xdc, 0xb2, 0x31, 0x1d, 0xfe, 0xcb, 0xd5, + 0x20, 0x8a, 0x67, 0x5b, 0x70, 0x63, 0x65, 0xcb, 0xb6, 0xbd, 0xc4, 0xc7, + 0x22, 0x30, 0xfc, 0x59, 0x27, 0xe9, 0xe3, 0x4, 0x8, 0x5c, 0x73, 0x4a, + 0xbf, 0xb5, 0xb, 0x5b, 0xd5, 0x90, 0x25, 0x97, 0xa9, 0xe5, 0x85, 0xd3, + 0x63, 0xdc, 0x36, 0x1b, 0xc8, 0x33, 0xf5, 0x6d, 0x17, 0x45, 0xb8, 0x1b, + 0x21, 0x36, 0xc4, 0xee, 0x33, 0x8b, 0x14, 0x4, 0x4c, 0x99, 0x1d, 0xbe, + 0x7a, 0xd2, 0x36, 0x5c, 0x9e, 0xec, 0x57, 0xb6, 0x2b, 0x5b, 0x36, 0x84, + 0xa8, 0x92, 0xa0, 0xee, 0xca, 0x21, 0x6a, 0x73, 0x9d, 0x2f, 0xb7, 0x80, + 0x20, 0xc9, 0x48, 0xc5, 0xd6, 0xba, 0x9, 0xdb, 0x8a, 0xa9, 0xcf, 0xb7, + 0xd5, 0xb0, 0xa0, 0x39, 0xd6, 0xd0, 0xaf, 0xd9, 0xe8, 0xf2, 0x26, 0x2d, + 0x52, 0x0, 0x90, 0x22, 0xad, 0xcb, 0xab, 0x66, 0x8b, 0x0, 0x2a, 0x10, + 0x56, 0xc1, 0xf0, 0xb1, 0x10, 0x52, 0x7b, 0x7f, 0xca, 0x2d, 0x5d, 0x2, + 0x3b, 0xf5, 0x62, 0xd0, 0x73, 0x83, 0xc8, 0x8e, 0xf0, 0x73, 0xbe, 0xe7, + 0xde, 0xae, 0x14, 0x94, 0xc, 0x3b, 0xfd, 0xfb, 0xc6, 0x36, 0xe0, 0xc1, + 0xaa, 0xce, 0xbe, 0x9d, 0x15, 0x36, 0x59, 0x78, 0x55, 0xc2, 0x69, 0x3, + 0x7d, 0xf7, 0x86, 0xc7, 0xbc, 0x88, 0x60, 0x9d, 0x55, 0x44, 0xa6, 0xf7, + 0x1, 0x9a, 0xe0, 0x3b, 0xe4, 0x4c, 0x1d, 0x69, 0xc8, 0xa6, 0xe6, 0xd3, + 0x9c, 0xd8, 0xfe, 0xbe, 0x8a, 0x64, 0x79, 0x65, 0xdd, 0x98, 0x8f, 0x50, + 0x5d, 0x16, 0xc6, 0x9, 0x5a, 0x19, 0x3f, 0x58, 0xd, 0xd, 0xc, 0x74, + 0x5d, 0xe2, 0x91, 0xbf, 0x86, 0x5e, 0xb6, 0x8, 0x9, 0xd, 0xf9, 0x3a, + 0xd0, 0xf0, 0x76, 0x3, 0xf3, 0x5d, 0xed, 0x50, 0xc8, 0x2f, 0xce, 0xa0, + 0x59, 0x21, 0xab, 0x66, 0xef, 0x85, 0x5b, 0xf2, 0xb7, 0x11, 0x9c, 0xbb, + 0xbc, 0xa9, 0xc4, 0xc0, 0x91, 0x82, 0x33, 0xba, 0x9e, 0xa0, 0x63, 0x4a, + 0xa2, 0x44, 0x6a, 0x3f, 0x8, 0x38, 0x47, 0x9, 0xb6, 0x53, 0xa2, 0x33, + 0x2e, 0x4d, 0x98, 0xc7, 0x40, 0xa5, 0x22, 0x5, 0x3e, 0xbd, 0x24, 0x25, + 0x78, 0x50, 0xe7, 0x52, 0xb, 0x23, 0xfe, 0xa5, 0xa3, 0x21, 0x53, 0x3d, + 0x8c, 0x56, 0x73, 0x5e, 0xda, 0x17, 0x1b, 0x33, 0xd7, 0x7f, 0xca, 0xce, + 0xcd, 0xfd, 0x36, 0x48, 0x43, 0x1b, 0x6, 0x80, 0x68, 0xf9, 0x91, 0x58, + 0x9e, 0x41, 0xa4, 0xbd, 0xef, 0xc0, 0x45, 0x98, 0x1f, 0x75, 0x8e, 0x38, + 0x94, 0x21, 0xa4, 0x91, 0xaa, 0x28, 0x43, 0x27, 0x90, 0xe8, 0x7e, 0xd4, + 0x15, 0x99, 0x74, 0xc3, 0xff, 0x37, 0xea, 0x77, 0xe0, 0xef, 0x8, 0xf3, + 0xe9, 0x10, 0xbc, 0xf1, 0xc5, 0xa2, 0x2c, 0x84, 0x82, 0xf6, 0x92, 0x56, + 0xd7, 0xf8, 0x50, 0xc2, 0xb9, 0xc4, 0xcd, 0xcc, 0xc7, 0xb1, 0x8b, 0xd9, + 0xc1, 0xad, 0xb6, 0x86, 0xfe, 0xca, 0x17, 0x28, 0xe9, 0x15, 0xba, 0xdb, + 0x51, 0x84, 0x69, 0xa8, 0x22, 0x62, 0x6f, 0x93, 0x3b, 0xfe, 0xcc, 0x6e, + 0x3f, 0xed, 0x3a, 0x8d, 0x7b, 0x92, 0xc9, 0xff, 0xcd, 0x49, 0xb2, 0x6f, + 0x3, 0x89, 0xda, 0xb6, 0x20, 0xcb, 0x2b, 0x9a, 0x23, 0x38, 0x57, 0xd7, + 0xfe, 0xaf, 0x9d, 0xed, 0x8f, 0x5a, 0x23, 0xa0, 0x9, 0xba, 0x12, 0x5b, + 0x57, 0x79, 0x53, 0x3e, 0x67, 0xa2, 0xf7, 0x6a, 0x96, 0xc5, 0xd5, 0x79, + 0xde, 0xf8, 0xd0, 0x70, 0xb6, 0xce, 0x34, 0xb1, 0xfe, 0xa7, 0xe, 0x7c, + 0xbf, 0x73, 0x31, 0x4f, 0x7d, 0xfc, 0x88, 0xaa, 0x55, 0x2d, 0xb, 0x2c, + 0x49, 0xbc, 0xd7, 0x57, 0xf6, 0xe1, 0xb6, 0xc2, 0x4, 0x67, 0x6, 0x4a, + 0x9e, 0x72, 0xc7, 0x7b, 0xa, 0x77, 0x0, 0x46, 0x64, 0xa9, 0xa3, 0x55, + 0x49, 0xe3, 0xfc, 0xf6, 0x46, 0x59, 0x61, 0xc7, 0x2b, 0x8d, 0xca, 0xe3, + 0x41, 0x5f, 0xca, 0x9b, 0xfe, 0xac, 0xe6, 0xdd, 0x50, 0xd6, 0xa8, 0x4, + 0x38, 0x16, 0x55, 0x29, 0x90, 0xae, 0x55, 0x68, 0x4, 0xa8, 0xe1, 0xc, + 0x88, 0xdc, 0xad, 0x41, 0x37, 0x64, 0xab, 0x5f, 0x28, 0xce, 0xfe, 0x75, + 0x64, 0xe1, 0x43, 0xf3, 0x17, 0x69, 0x1c, 0xe8, 0x61, 0x9e, 0x78, 0xe6, + 0xe2, 0xf2, 0x3a, 0xc4, 0x6a, 0x89, 0xd2, 0x80, 0xbf, 0xc, 0xfa, 0xaa, + 0x1b, 0x54, 0xc0, 0x5a, 0x3a, 0x4e, 0xe6, 0x35, 0x52, 0x7f, 0x68, 0xcc, + 0x7, 0xfe, 0xb3, 0xd2, 0xc7, 0x32, 0x7b, 0xea, 0x98, 0x76, 0x68, 0xc2, + 0xd1, 0x43, 0x62, 0xf, 0xdf, 0x71, 0x36, 0x1e, 0x78, 0x8f, 0xd9, 0x6a, + 0xb1, 0xc5, 0xb8, 0x18, 0xc0, 0xc, 0x2f, 0xc9, 0x73, 0x7e, 0x8f, 0xcd, + 0x34, 0x84, 0x25, 0x97, 0x7, 0x17, 0xb3, 0xb2, 0xbd, 0x11, 0xd0, 0x96, + 0x6f, 0x81, 0x61, 0x72, 0x73, 0x9b, 0x1c, 0xe3, 0xd8, 0x3e, 0x1a, 0x42, + 0xc5, 0xd1, 0xd5, 0xec, 0x46, 0x55, 0x14, 0x4f, 0x91, 0xd8, 0x56, 0x17, + 0x4d, 0xa2, 0xca, 0xa5, 0x6d, 0x8b, 0x33, 0x73, 0xa4, 0x1d, 0x79, 0xac, + 0x14, 0x33, 0xc8, 0x17, 0x3f, 0xde, 0xca, 0x99, 0xb5, 0xb5, 0x29, 0x1e, + 0xbb, 0x86, 0x43, 0x64, 0xb1, 0x5b, 0xc0, 0x6d, 0x49, 0x49, 0x4e, 0x85, + 0x52, 0x36, 0x11, 0xee, 0x7c, 0xc1, 0x29, 0x7d, 0x1b, 0xa8, 0x78, 0xeb, + 0x93, 0x32, 0x51, 0x32, 0xad, 0x0, 0xb0, 0x20, 0x40, 0xdd, 0xb2, 0xac, + 0x7e, 0x93, 0x92, 0x4, 0x76, 0xe, 0x99, 0x8e, 0xc1, 0x85, 0xb4, 0xa3, + 0xfb, 0xf5, 0x4f, 0xc9, 0x60, 0x91, 0x71, 0xe7, 0x5a, 0x2e, 0xf8, 0x35, + 0xbd, 0x54, 0x4f, 0xf3, 0xda, 0x6b, 0xb6, 0x32, 0x62, 0x88, 0x10, 0x44, + 0x79, 0x66, 0x4, 0x48, 0xd6, 0x6b, 0x6f, 0xef, 0xb5, 0x93, 0xd8, 0x5f, + 0x35, 0x45, 0x8d, 0xc9, 0x11, 0x27, 0xdb, 0x76, 0x39, 0x37, 0x7a, 0xd3, + 0xa9, 0xd, 0x82, 0xa5, 0x81, 0x47, 0xe0, 0x52, 0x1e, 0xad, 0xd9, 0x92, + 0x3a, 0x7d, 0xa8, 0xfe, 0x9b, 0x7b, 0x9c, 0x77, 0xbd, 0xdc, 0x2c, 0x23, + 0x49, 0x7c, 0x38, 0xd4, 0x8c, 0x4a, 0x1b, 0xb7, 0x5c, 0x45, 0x84, 0xdb, + 0xbc, 0xe2, 0xae, 0x32, 0xae, 0x9f, 0x85, 0x7b, 0x11, 0x68, 0xa1, 0x4e, + 0xd7, 0x9e, 0xc, 0x39, 0x27, 0xf4, 0x4e, 0x24, 0x56, 0x2c, 0x91, 0x32, + 0x68, 0x76, 0x70, 0xaa, 0xe4, 0x30, 0xaa, 0x46, 0x90, 0xbc, 0x2f, 0x6d, + 0x9a, 0xd9, 0x62, 0xe8, 0x79, 0x4d, 0x75, 0x7e, 0x27, 0x3, 0x9e, 0x37, + 0x24, 0xf5, 0x46, 0x8f, 0x87, 0xde, 0xd8, 0xec, 0xf0, 0xde, 0x8f, 0x5b, + 0x36, 0x5d, 0x9c, 0xf5, 0x95, 0x1d, 0xee, 0x31, 0x10, 0x83, 0xff, 0x1, + 0xab, 0xbb, 0xbb, 0x97, 0x1c, 0xd5, 0xbe, 0x58, 0xeb, 0xfe, 0xf7, 0x6d, + 0x38, 0xe6, 0x9c, 0xd4, 0x6b, 0x65, 0xa8, 0x58, 0x55, 0xb9, 0x2b, 0x2a, + 0x93, 0xd3, 0x4a, 0x3b, 0x6c, 0xa3, 0x8b, 0x58, 0x3e, 0xa0, 0x73, 0x96, + 0x68, 0x7f, 0xea, 0x8b, 0x9, 0xea, 0x8f, 0x9f, 0x68, 0x20, 0x45, 0xd2, + 0xe4, 0xf2, 0x2f, 0xdb, 0xd5, 0xac, 0xf2, 0xed, 0x77, 0xad, 0x3a, 0x33, + 0x9d, 0x67, 0x43, 0x25, 0x4, 0x2a, 0xdc, 0x3e, 0x35, 0xe, 0x71, 0xcf, + 0x90, 0x82, 0xc9, 0x7, 0x9a, 0xcb, 0x2, 0xc, 0x10, 0xad, 0x57, 0xe4, + 0xf8, 0x7b, 0x72, 0xe3, 0x89, 0xdb, 0xc7, 0x24, 0xe4, 0xe4, 0xc4, 0x2a, + 0xa, 0x71, 0x17, 0xf7, 0xe0, 0x9a, 0x15, 0x80, 0x4a, 0xce, 0x95, 0x7, + 0x7a, 0x32, 0x1, 0x81, 0x3c, 0xd6, 0x5a, 0xbe, 0xf8, 0x68, 0x12, 0x9f, + 0x62, 0x48, 0x46, 0x70, 0x42, 0xba, 0x8f, 0xe3, 0xaa, 0x1f, 0xaf, 0x72, + 0x8d, 0x1c, 0xa0, 0x67, 0xd4, 0xc6, 0xa2, 0xcf, 0x8b, 0xee, 0xff, 0x60, + 0x6c, 0x3e, 0x9b, 0xff, 0x69, 0xc4, 0x9d, 0xd2, 0x81, 0xf8, 0xa9, 0x58, + 0x37, 0x13, 0xc2, 0x47, 0x8a, 0x3, 0xf2, 0xf6, 0x1f, 0x98, 0xf0, 0x30, + 0xe7, 0x8f, 0x5b, 0xbb, 0xd, 0x67, 0xb1, 0x82, 0xe7, 0x16, 0x9a, 0x38, + 0x64, 0x61, 0xa6, 0x2a, 0xfe, 0x98, 0x79, 0x7e, 0xe4, 0x70, 0xb8, 0x62, + 0xdc, 0xe8, 0x2c, 0x84, 0xeb, 0x74, 0x77, 0x3c, 0xcf, 0x89, 0x14, 0xeb, + 0x5c, 0x9f, 0x63, 0x33, 0x37, 0x10, 0x86, 0xd9, 0xa0, 0x47, 0x57, 0x98, + 0x13, 0xc0, 0xcd, 0xfe, 0x2a, 0xd3, 0x64, 0x2d, 0x9f, 0xd, 0x48, 0x40, + 0xff, 0x14, 0x7a, 0xe5, 0xb2, 0x2d, 0x43, 0x6c, 0x90, 0xcd, 0x95, 0x6d, + 0x35, 0xec, 0x48, 0xb1, 0x77, 0x97, 0xf5, 0xca, 0x5a, 0x21, 0xf7, 0x6f, + 0x86, 0xcb, 0xa9, 0xce, 0xa7, 0xb, 0xb3, 0xe0, 0xc5, 0x27, 0x57, 0x83, + 0x32, 0xa6, 0x1a, 0x69, 0x5d, 0xd2, 0x62, 0xb1, 0x4a, 0x90, 0x9b, 0x6e, + 0x2a, 0xac, 0x44, 0x31, 0x22, 0x4f, 0x42, 0x6d, 0xa, 0xd5, 0x74, 0x2d, + 0xb8, 0xf9, 0xc3, 0x94, 0xd8, 0xa6, 0x8, 0xb3, 0x2b, 0x24, 0xe, 0xd, + 0xe8, 0x6f, 0x58, 0x66, 0x90, 0x73, 0x8f, 0x96, 0xb, 0xbb, 0xe9, 0xb1, + 0xfb, 0xb5, 0x2f, 0xd8, 0xbe, 0x4e, 0xf3, 0xc, 0x6, 0xfa, 0xa9, 0xd2, + 0x56, 0xe8, 0x17, 0x2e, 0x9a, 0x5f, 0x10, 0x19, 0x6d, 0x1a, 0x88, 0xd0, + 0x82, 0xbf, 0xc7, 0xe3, 0xae, 0xa4, 0xca, 0x36, 0x1a, 0xa6, 0x2d, 0x2, + 0xcd, 0x74, 0xbb, 0xdd, 0xf3, 0xf8, 0xea, 0x75, 0x15, 0xe2, 0x26, 0x2c, + 0x35, 0x9f, 0x6c, 0xd, 0xda, 0xe, 0xe2, 0xb, 0x24, 0x82, 0xd2, 0x44, + 0xb6, 0x6a, 0x9a, 0x11, 0xea, 0xd6, 0xb1, 0x2c, 0x13, 0x99, 0xb3, 0x63, + 0xc0, 0xce, 0xee, 0xcd, 0x75, 0x60, 0x72, 0xe2, 0x6b, 0x7a, 0xc5, 0xff, + 0xdf, 0x91, 0x0, 0xec, 0x49, 0xab, 0xc, 0xeb, 0x85, 0x6e, 0x13, 0x12, + 0xfc, 0x3c, 0x4f, 0x13, 0xae, 0x6c, 0xf2, 0xfa, 0x6a, 0x12, 0xc8, 0x32, + 0x77, 0x4a, 0xb5, 0x13, 0x82, 0xa4, 0x1d, 0x39, 0x18, 0x27, 0xd3, 0x3e, + 0x42, 0xb0, 0xf1, 0xd0, 0xa1, 0x84, 0xc9, 0xe4, 0x9b, 0x90, 0x40, 0xf8, + 0xf4, 0x5a, 0xde, 0xd3, 0x48, 0x61, 0x48, 0xfa, 0xfa, 0xa7, 0x31, 0xf5, + 0x4d, 0xd0, 0x9b, 0xad, 0xcc, 0xd0, 0x9c, 0xc8, 0x56, 0x4, 0xa0, 0xc0, + 0x9b, 0xc5, 0xd8, 0x77, 0xd0, 0x2, 0x25, 0x7, 0xce, 0xde, 0x4a, 0xd6, + 0xd7, 0x9d, 0xe9, 0xc8, 0xe8, 0x2b, 0x5, 0x79, 0xd5, 0x37, 0x84, 0xff, + 0xd4, 0x79, 0x62, 0x2, 0x6e, 0xbe, 0x6e, 0xb5, 0xa2, 0x82, 0x70, 0x1a, + 0x3a, 0x43, 0x83, 0xd0, 0x3f, 0xd4, 0xcb, 0xe9, 0x73, 0x25, 0xf7, 0x72, + 0x83, 0x20, 0x6f, 0x14, 0x73, 0x3a, 0x4a, 0xba, 0x5b, 0x3d, 0xaa, 0xb9, + 0xa0, 0xf9, 0xc7, 0x30, 0x7e, 0xe2, 0xfe, 0xb3, 0x1c, 0x10, 0x5f, 0xb9, + 0x91, 0x73, 0x11, 0x3e, 0x9, 0xee, 0xb3, 0x5e, 0x72, 0x62, 0x86, 0xfb, + 0xdd, 0x27, 0xd4, 0xbb, 0xe3, 0x75, 0xa9, 0xba, 0x42, 0xad, 0xaa, 0xbf, + 0x1c, 0x3f, 0x32, 0x27, 0xe7, 0x2f, 0xeb, 0x34, 0x75, 0x3d, 0xda, 0x82, + 0x9b, 0x76, 0x1e, 0xbd, 0x76, 0x9a, 0xe0, 0x7, 0xb8, 0xa6, 0xa7, 0x68, + 0xbe, 0x1e, 0x5, 0x97, 0x15, 0x16, 0x1c, 0x6b, 0xb6, 0x94, 0xf1, 0x0, + 0x79, 0x1a, 0x54, 0x8e, 0x48, 0xbc, 0x45, 0x5c, 0x76, 0xd9, 0xdf, 0xc3, + 0xc2, 0xd8, 0x4c, 0xa4, 0xa3, 0x3, 0xff, 0x96, 0xac, 0x68, 0xd, 0x47, + 0xe7, 0x8f, 0x72, 0x13, 0x72, 0x6f, 0xc8, 0x1, 0x4f, 0xe4, 0xf1, 0x2d, + 0x6c, 0x61, 0x1e, 0x35, 0x71, 0xd, 0xdd, 0x6a, 0xa, 0xf6, 0xfb, 0x1a, + 0xf1, 0x92, 0xb6, 0x88, 0xc6, 0xe5, 0x78, 0xac, 0xed, 0x6c, 0xba, 0xcd, + 0xec, 0x51, 0x4d, 0xb1, 0x6b, 0x70, 0x8b, 0x35, 0x9f, 0xbc, 0xa5, 0xdc, + 0x8b, 0x16, 0x4e, 0x23, 0x6, 0x47, 0xb0, 0x73, 0x9a, 0x2, 0x1f, 0xcf, + 0x12, 0x6b, 0xd4, 0x65, 0x8f, 0x7e, 0x11, 0xf0, 0xa3, 0x88, 0xdf, 0x2c, + 0x6b, 0xda, 0x7a, 0xd0, 0x7c, 0x35, 0xe1, 0x7f, 0x53, 0x63, 0x53, 0x59, + 0x88, 0x71, 0xcc, 0x43, 0x5, 0x7e, 0xbd, 0x6f, 0xfa, 0xe2, 0xfb, 0x2a, + 0xec, 0xf9, 0x6f, 0x46, 0x82, 0x1, 0xa8, 0x3, 0xa6, 0xa3, 0x8a, 0x2d, + 0x52, 0xc4, 0xaf, 0xa2, 0x47, 0x2f, 0x77, 0xd6, 0x2f, 0xbe, 0x61, 0xa0, + 0x38, 0xa7, 0xee, 0xe2, 0xe8, 0xc9, 0x1b, 0x67, 0x84, 0xe, 0x3c, 0xdc, + 0x7, 0xe9, 0x4d, 0xec, 0x18, 0x18, 0xa6, 0xc, 0xbb, 0x24, 0xbd, 0xc5, + 0x2c, 0xd6, 0x71, 0x15, 0xe6, 0xe9, 0x21, 0x14, 0xb4, 0x3b, 0xa0, 0x51, + 0x2d, 0x9b, 0xb2, 0x36, 0x65, 0xc7, 0xbc, 0x47, 0x54, 0x95, 0x9c, 0x1d, + 0xca, 0x60, 0x5d, 0xed, 0x36, 0xce, 0x87, 0x18, 0xe6, 0x71, 0x9e, 0x33, + 0x69, 0x1b, 0xe6, 0x19, 0x3f, 0x88, 0x8b, 0xf5, 0xdd, 0xd0, 0x1, 0x7, + 0x5c, 0xba, 0xa2, 0xe5, 0x3a, 0x7a, 0xf0, 0xa1, 0x38, 0x1a, 0x43, 0x7c, + 0x3b, 0xed, 0x96, 0x63, 0x50, 0x64, 0x1e, 0x37, 0x85, 0xbe, 0x87, 0x79, + 0x2b, 0x42, 0xb9, 0x2c, 0xb7, 0x3c, 0xea, 0x0, 0xdb, 0x53, 0x43, 0xbb, + 0xef, 0x8c, 0x30, 0xc7, 0xea, 0x20, 0x4d, 0x60, 0x79, 0x61, 0xdb, 0x26, + 0x84, 0x79, 0x57, 0x2d, 0xd, 0xcd, 0x27, 0xef, 0x16, 0xba, 0x3a, 0xf7, + 0x1, 0x90, 0x50, 0xa2, 0x3e, 0x83, 0x8c, 0xd2, 0x8a, 0x5c, 0xf, 0x26, + 0x4e, 0x7b, 0x7, 0x2b, 0xba, 0xd5, 0xd, 0xe3, 0x66, 0xe2, 0x86, 0xa5, + 0xda, 0x46, 0xe6, 0xda, 0x17, 0x33, 0xce, 0x8, 0x73, 0x31, 0x7c, 0x96, + 0xd8, 0x4f, 0x6d, 0x42, 0xb0, 0xdd, 0x24, 0xd, 0xd5, 0x36, 0x88, 0xd8, + 0xe, 0x6e, 0xd2, 0x49, 0x31, 0x7d, 0x3f, 0x9d, 0xe9, 0x4, 0xb, 0x2a, + 0xf9, 0x86, 0xb6, 0xa3, 0x5d, 0x21, 0x84, 0x8b, 0x8b, 0xd1, 0x91, 0x30, + 0xfa, 0xbb, 0x63, 0xc2, 0x9a, 0xc, 0x3b, 0xbe, 0xd2, 0x8, 0xb1, 0x84, + 0x8f, 0xa6, 0x59, 0x88, 0x4b, 0xbf, 0x99, 0xa1, 0xfc, 0xef, 0x1f, 0x49, + 0xd8, 0x3f, 0xdf, 0xd5, 0x9e, 0x3c, 0xfa, 0x91, 0x10, 0xe5, 0x8e, 0xb, + 0x33, 0x37, 0x47, 0xc6, 0xea, 0x44, 0xb5, 0xfd, 0xa9, 0x12, 0x67, 0x6c, + 0x47, 0xb5, 0x57, 0xa3, 0xa, 0x9c, 0x82, 0x1a, 0xd8, 0x7b, 0x9c, 0x81, + 0xbb, 0x2f, 0x10, 0x65, 0x9f, 0x27, 0xb4, 0x94, 0xc7, 0xa5, 0x85, 0x89, + 0x31, 0x74, 0xc6, 0x71, 0xb0, 0xff, 0xe5, 0x23, 0x1a, 0x22, 0x7a, 0xa7, + 0xdd, 0x23, 0x37, 0x99, 0x5f, 0x35, 0xd0, 0x2b, 0x61, 0xc, 0x2d, 0xe3, + 0xa8, 0x62, 0xce, 0xf7, 0xf6, 0x80, 0xdf, 0x96, 0x91, 0xa6, 0xf8, 0x4, + 0x71, 0xf6, 0x9e, 0xdb, 0xea, 0x76, 0xb4, 0x5, 0x16, 0x49, 0xd8, 0x1e, + 0x84, 0xd2, 0xb6, 0xbb, 0x2b, 0x1c, 0x2, 0x55, 0xb9, 0xc5, 0x25, 0x35, + 0xa3, 0x8, 0xd1, 0x3b, 0x31, 0xe3, 0xde, 0xc4, 0x69, 0x1c, 0x6, 0x3f, + 0xc4, 0x78, 0xc3, 0x65, 0x4c, 0xdc, 0xe1, 0xa5, 0xc6, 0xc7, 0xa, 0xb4, + 0xdb, 0x28, 0x42, 0x45, 0x90, 0x62, 0x31, 0x8a, 0xc3, 0xe, 0xfa, 0xf4, + 0xd, 0x62, 0x17, 0x54, 0x38, 0x2d, 0x74, 0xa, 0x46, 0xaf, 0xc8, 0x85, + 0xf8, 0x7e, 0x2d, 0xe, 0x8d, 0xed, 0x4f, 0x4c, 0xb1, 0x22, 0xa1, 0x8d, + 0xf4, 0xf2, 0xc0, 0xab, 0x27, 0xa8, 0x8, 0x52, 0x3, 0x66, 0x35, 0xa1, + 0x25, 0x8e, 0xe4, 0xca, 0x2a, 0xec, 0x75, 0xd9, 0x55, 0x49, 0xaf, 0xa, + 0x4d, 0xe4, 0x63, 0x92, 0x8c, 0x56, 0x58, 0x4f, 0xe2, 0x19, 0xab, 0x2f, + 0x6a, 0xe, 0x9d, 0x3d, 0x3, 0xaf, 0x38, 0x25, 0xd8, 0x94, 0x61, 0xb6, + 0xac, 0x82, 0x44, 0xb7, 0xcc, 0xe1, 0x8d, 0x3, 0xde, 0x31, 0x5b, 0xc8, + 0x1c, 0x8b, 0x79, 0x74, 0xb8, 0xdd, 0xf1, 0x85, 0x7d, 0x79, 0x19, 0x90, + 0x5e, 0x99, 0xf8, 0xec, 0x5c, 0x80, 0x6f, 0x46, 0x69, 0xc3, 0xef, 0x7a, + 0x69, 0x7d, 0x1b, 0x7c, 0x2a, 0xbb, 0xfe, 0xe6, 0xc3, 0xb9, 0x9f, 0xe, + 0x81, 0xba, 0xd7, 0x50, 0x87, 0x72, 0x8d, 0x1c, 0x98, 0xd5, 0xc2, 0x21, + 0x8a, 0xa2, 0xef, 0x16, 0x76, 0xdc, 0x62, 0x52, 0x64, 0x86, 0x60, 0xa2, + 0x1, 0xa9, 0x68, 0xd2, 0x28, 0x44, 0x71, 0x42, 0xbd, 0xcb, 0xf8, 0xa9, + 0x32, 0x29, 0x99, 0xcb, 0x1d, 0xe8, 0xfe, 0xf4, 0x89, 0xf, 0x32, 0x7e, + 0x3d, 0x9d, 0x49, 0xc9, 0x2, 0xdf, 0x55, 0xed, 0xac, 0x7a, 0xee, 0x9e, + 0x28, 0x9d, 0xd3, 0xe4, 0xe0, 0x5e, 0xc3, 0x37, 0xe6, 0x2b, 0x3d, 0xf0, + 0xc3, 0x1e, 0xd8, 0x3f, 0x14, 0x63, 0x5f, 0x7, 0xbc, 0x88, 0x2, 0xcd, + 0x43, 0xc0, 0x27, 0x3e, 0x6a, 0xe0, 0x56, 0xc9, 0x95, 0x9b, 0xf4, 0xaf, + 0x6e, 0xf6, 0xe4, 0x41, 0xba, 0x53, 0xd2, 0x44, 0xbd, 0x40, 0xf7, 0x41, + 0x3a, 0xf7, 0x75, 0x85, 0xd0, 0x62, 0x2d, 0x8b, 0x33, 0x7a, 0x48, 0xd0, + 0x8d, 0xa5, 0xe8, 0xdb, 0x7a, 0x98, 0xd6, 0x79, 0xc2, 0xa5, 0x19, 0xef, + 0xd6, 0x5, 0x49, 0x67, 0xde, 0xe1, 0x7e, 0xb9, 0xa6, 0xc6, 0x5a, 0xdb, + 0x9, 0x7a, 0x51, 0x3f, 0x71, 0xb3, 0x48, 0x15, 0xc3, 0xaf, 0x4e, 0x76, + 0x4e, 0xf1, 0xc8, 0x7a, 0x3, 0xf9, 0x8a, 0xb2, 0xd3, 0x7, 0x3b, 0xe4, + 0x2a, 0x6f, 0x41, 0x69, 0xdf, 0xa, 0x62, 0x31, 0x4a, 0x9c, 0xce, 0xca, + 0x7c, 0x3e, 0xdf, 0xf5, 0xb, 0x25, 0x59, 0xcb, 0xee, 0x48, 0x6a, 0xbd, + 0x68, 0xae, 0x7d, 0xb8, 0xfa, 0x83, 0xe, 0x6d, 0xbd, 0x87, 0x72, 0x4e, + 0x43, 0xb, 0xfa, 0xc4, 0x78, 0x32, 0x99, 0xa4, 0x8, 0x97, 0xdf, 0x3, + 0x54, 0x56, 0x47, 0x67, 0x2f, 0xd0, 0xa7, 0xaf, 0x7a, 0xc, 0x37, 0x9a, + 0xce, 0xc9, 0x60, 0x4, 0xb8, 0xb1, 0xf6, 0x12, 0x7e, 0xdf, 0x7c, 0x2f, + 0xb9, 0x5d, 0xbf, 0x4b, 0x68, 0xdc, 0x48, 0xa5, 0xd4, 0x74, 0x8, 0xe0, + 0x11, 0xfe, 0x12, 0xcd, 0x5f, 0x6f, 0x8a, 0xb, 0x76, 0x1e, 0xd8, 0x70, + 0xc5, 0x2c, 0xa1, 0xdd, 0x2f, 0x97, 0xe6, 0x7c, 0xa1, 0x7, 0xad, 0xb0, + 0xb1, 0x61, 0xdb, 0x72, 0x3b, 0xdd, 0x81, 0x99, 0xfa, 0x45, 0x9b, 0xe2, + 0xc4, 0x22, 0x4b, 0x4, 0x4e, 0x29, 0x0, 0xcb, 0xf8, 0x12, 0x5b, 0xa1, + 0xc3, 0xf2, 0x41, 0xdc, 0x59, 0x30, 0x13, 0x59, 0xb1, 0x43, 0x25, 0xfa, + 0x54, 0xc0, 0x70, 0x43, 0xe3, 0x5d, 0xcd, 0x96, 0x68, 0xb1, 0x99, 0xe7, + 0x94, 0xf1, 0xd7, 0xd3, 0x6b, 0xb, 0x2c, 0x18, 0x61, 0xba, 0x34, 0x8, + 0x94, 0x57, 0xb3, 0xe2, 0x5f, 0x8e, 0x2b, 0x3a, 0x32, 0x3a, 0xa1, 0x74, + 0xbf, 0xfd, 0xbf, 0x2a, 0xe3, 0xd8, 0xd7, 0x5c, 0xb6, 0x12, 0xd5, 0x34, + 0xb6, 0xdc, 0x5b, 0xb8, 0xb1, 0xf2, 0xf9, 0x2f, 0xc5, 0x87, 0x93, 0x4e, + 0xc0, 0x86, 0xfa, 0x68, 0x4, 0x42, 0x4c, 0x92, 0x1, 0x53, 0xc2, 0x6a, + 0xe2, 0xb7, 0xcd, 0x28, 0xb2, 0xaf, 0x3e, 0xf6, 0x8f, 0x4e, 0xf9, 0xbd, + 0xa4, 0x6c, 0x86, 0x50, 0xed, 0x21, 0xfb, 0xbf, 0x21, 0xfd, 0x20, 0xee, + 0x49, 0x67, 0x52, 0x3e, 0x42, 0x3a, 0x56, 0xe5, 0x61, 0x36, 0xdc, 0xdc, + 0xf3, 0x7, 0xa5, 0xe6, 0x17, 0x9b, 0x50, 0x53, 0x1d, 0xc1, 0xa9, 0x6c, + 0x2c, 0xde, 0x37, 0x57, 0xee, 0x47, 0x66, 0xba, 0xb8, 0xe8, 0xdc, 0xdd, + 0x5e, 0x7a, 0x18, 0x11, 0x5a, 0xad, 0xb1, 0xcd, 0xff, 0x45, 0xc6, 0xb9, + 0x91, 0xab, 0x6f, 0x9, 0xf7, 0xbb, 0x7e, 0x51, 0x82, 0x7d, 0x96, 0x80, + 0x32, 0xfd, 0x96, 0x79, 0x20, 0x39, 0x18, 0x1, 0x83, 0x6e, 0x53, 0x2a, + 0xde, 0xa9, 0xe5, 0x38, 0x4e, 0x5d, 0x2f, 0x29, 0xc0, 0xc3, 0x33, 0x2f, + 0xb1, 0xbe, 0x41, 0x5e, 0x6f, 0xe3, 0xe5, 0x9, 0x97, 0x58, 0xad, 0xdb, + 0x6c, 0x83, 0xc6, 0x3a, 0xaa, 0x91, 0x36, 0xd8, 0x1b, 0x9a, 0x83, 0x7d, }; -const size_t kAltGameImages1xLength[] = { - 624, 2816, 2448, 3312, 1808, 2288, +const size_t kAltGameImages1xOffsets[] = { + 0, 442, 2532, 4347, 6808, 8136, }; -const char* kAltGameImages2x[] = { - (char[]){ - 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, - }, - (char[]){ - 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, - }, - (char[]){ - 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, - }, - (char[]){ - 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, - }, - (char[]){ - 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, - }, - (char[]){ - 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 size_t kAltGameImages1xSizes[] = { + 442, 2090, 1815, 2461, 1328, 1696, }; -const size_t kAltGameImages2xLength[] = { - 752, 3968, 4288, 4576, 2432, 3280, +const uint8_t kAltGameImages2x[] = { + 0xeb, 0xe7, 0xf9, 0x37, 0x6, 0xbc, 0x45, 0x28, 0x6c, 0xb4, 0x8d, 0x4b, + 0xe8, 0xe3, 0x40, 0x2d, 0xcb, 0x52, 0x9e, 0xe4, 0x8b, 0x1c, 0x41, 0xb6, + 0x78, 0x4, 0x8e, 0x9f, 0x19, 0xc, 0xc3, 0x73, 0x2f, 0xf7, 0xcf, 0x33, + 0xbf, 0x16, 0x8f, 0x1a, 0x8a, 0x56, 0x88, 0x72, 0xd, 0xe9, 0xf1, 0x71, + 0x25, 0x77, 0x57, 0x3a, 0x85, 0x33, 0x74, 0x6f, 0x89, 0xe, 0x4a, 0xe8, + 0x6, 0x91, 0x3a, 0xdc, 0x69, 0x5f, 0x1c, 0xc8, 0x26, 0xcf, 0x46, 0x37, + 0xd6, 0x4b, 0x16, 0x7f, 0x38, 0x63, 0x60, 0x98, 0xab, 0x61, 0xbb, 0x59, + 0xe, 0xa2, 0x77, 0x12, 0xf4, 0xe2, 0xfd, 0x4a, 0x87, 0xc7, 0x10, 0xdf, + 0x94, 0x8a, 0x21, 0xca, 0x21, 0xe2, 0x97, 0x3c, 0xd2, 0xf0, 0xdc, 0xc2, + 0x84, 0xf8, 0x2c, 0x62, 0xd1, 0xed, 0xd9, 0xca, 0x64, 0x8a, 0x5d, 0x12, + 0x6a, 0x3a, 0xb4, 0xa0, 0x14, 0x26, 0xc5, 0xe0, 0x64, 0xca, 0x8f, 0xff, + 0x8, 0xfb, 0xc7, 0x45, 0x32, 0x28, 0x9c, 0x4d, 0xa6, 0xf6, 0xf4, 0x6a, + 0xf6, 0x89, 0x6f, 0xeb, 0xec, 0xf4, 0xeb, 0x51, 0xeb, 0x14, 0x28, 0x1, + 0x43, 0x60, 0x73, 0xf1, 0xfe, 0x5a, 0xe7, 0xec, 0xc8, 0x5c, 0xb9, 0x3a, + 0x81, 0x35, 0xe1, 0xa0, 0x2d, 0xf8, 0x49, 0xcf, 0x32, 0xe5, 0x71, 0xf2, + 0xc, 0xe5, 0x7, 0xec, 0xa9, 0xb2, 0x6b, 0x8b, 0x36, 0x2f, 0x13, 0x3c, + 0x1a, 0x3, 0xdd, 0x8a, 0x66, 0x58, 0x98, 0x1d, 0x75, 0x28, 0x27, 0x4d, + 0xc9, 0x56, 0x4d, 0x82, 0x20, 0x1c, 0xb7, 0xf3, 0xbf, 0x17, 0xb8, 0x4e, + 0x49, 0x9d, 0xee, 0xe, 0x25, 0xcb, 0x29, 0x34, 0xdb, 0x73, 0x7c, 0x8, + 0x1f, 0x67, 0xe7, 0x3e, 0x9a, 0xb5, 0xba, 0x6b, 0xd4, 0xb6, 0x61, 0x9c, + 0xb1, 0x11, 0x63, 0x3d, 0x44, 0xb2, 0xa0, 0xe2, 0x9e, 0xc6, 0xe6, 0x76, + 0x8d, 0x9c, 0xf2, 0x7a, 0xd7, 0x98, 0xeb, 0xac, 0xcd, 0x7f, 0x5, 0x55, + 0xc4, 0xac, 0x18, 0x1, 0xa5, 0x5c, 0x3d, 0x2e, 0x75, 0x61, 0xee, 0xd, + 0x76, 0x53, 0x8c, 0x67, 0x44, 0xb2, 0xc3, 0xe8, 0x7a, 0x71, 0x93, 0xc6, + 0xba, 0x6, 0x81, 0xb2, 0xec, 0xb0, 0x5f, 0xcb, 0x14, 0xb1, 0xff, 0x9e, + 0x14, 0xdf, 0x7, 0x72, 0x7c, 0x7, 0x3c, 0x58, 0xa, 0x23, 0x8, 0x98, + 0x2c, 0x60, 0x11, 0x0, 0x1e, 0x54, 0xb5, 0x87, 0xe2, 0x4d, 0x34, 0xd, + 0xb1, 0x1d, 0x56, 0xe6, 0x14, 0x96, 0x8, 0xb9, 0x4f, 0x75, 0xf, 0xff, + 0x2, 0xf3, 0x3a, 0xb7, 0x5b, 0x73, 0x30, 0x60, 0x71, 0x4b, 0x89, 0x81, + 0xd4, 0x67, 0xb1, 0x91, 0x95, 0xa0, 0x49, 0xf, 0xd0, 0x7c, 0xe8, 0x4c, + 0xd4, 0x9c, 0xfa, 0x8, 0x88, 0x6c, 0x7b, 0xf, 0x91, 0x25, 0xc3, 0xea, + 0xbd, 0x60, 0x4f, 0xa4, 0x77, 0x42, 0xd2, 0x1d, 0x6f, 0xe0, 0x6, 0x52, + 0x48, 0x74, 0x6f, 0xe1, 0xdc, 0x4, 0x6, 0xaa, 0xc7, 0x5d, 0xcb, 0xb7, + 0xef, 0x11, 0xa2, 0x58, 0x36, 0x17, 0xed, 0x7b, 0x71, 0x4c, 0x77, 0x3e, + 0x9a, 0xe8, 0x21, 0xef, 0x5, 0x8c, 0x22, 0x7f, 0xf9, 0xce, 0x81, 0x2, + 0x88, 0xb7, 0xb3, 0x0, 0xe6, 0xd1, 0x1a, 0xe8, 0x9c, 0x29, 0x8c, 0x1d, + 0x48, 0xe8, 0x45, 0xef, 0x52, 0x88, 0x4c, 0x67, 0x20, 0xa2, 0x3c, 0xad, + 0x9d, 0x81, 0x4, 0x5e, 0xa0, 0x34, 0xe0, 0x3, 0x5d, 0x6e, 0xf4, 0x4f, + 0xd3, 0x3c, 0xd6, 0x2, 0x77, 0x46, 0xc8, 0x5c, 0x34, 0x5d, 0xd0, 0xb2, + 0x4, 0xa4, 0xb0, 0xc2, 0xa6, 0x91, 0xe, 0x18, 0x6d, 0xb9, 0x25, 0x14, + 0xfb, 0xb6, 0x88, 0xdd, 0x23, 0xae, 0x27, 0xd0, 0xa7, 0x53, 0x16, 0xe1, + 0x4a, 0x57, 0x9d, 0xe3, 0x38, 0xa0, 0x92, 0x58, 0xb0, 0x32, 0x49, 0xb, + 0xb4, 0xd0, 0x9, 0x8c, 0x48, 0xc9, 0x47, 0x48, 0xdb, 0x34, 0x4e, 0xce, + 0x90, 0xcc, 0x4e, 0x22, 0x1a, 0xcd, 0xf1, 0x99, 0x5b, 0x82, 0xeb, 0xe3, + 0x84, 0xea, 0x4d, 0x68, 0xe7, 0xa0, 0x2f, 0x7d, 0xa4, 0xf6, 0x6b, 0x1c, + 0xde, 0xad, 0x9f, 0x6, 0x47, 0x3d, 0x86, 0x1c, 0x75, 0x23, 0xe2, 0x99, + 0x44, 0xdc, 0x0, 0x90, 0xf4, 0x31, 0x40, 0xcb, 0xd5, 0x12, 0x89, 0xaa, + 0x23, 0xa3, 0x4f, 0xa9, 0xf5, 0x33, 0xd1, 0xee, 0xaa, 0xa3, 0x25, 0x2e, + 0x7e, 0xaf, 0xfc, 0x5f, 0x6f, 0x4c, 0x40, 0x85, 0x66, 0x60, 0x3c, 0x18, + 0x3a, 0x90, 0x64, 0xe9, 0xb0, 0x85, 0xb3, 0xca, 0xd3, 0xbd, 0xa5, 0x87, + 0x2, 0x13, 0x74, 0xc2, 0xcd, 0xd1, 0x59, 0xdc, 0xcb, 0x2f, 0xc8, 0x9f, + 0xfe, 0x7e, 0x9b, 0xdf, 0x8a, 0xe, 0x55, 0x91, 0xd5, 0x92, 0x53, 0xc6, + 0x5c, 0x6b, 0x46, 0xd6, 0xdf, 0xe7, 0xf9, 0x7c, 0xda, 0x3b, 0xcd, 0x2d, + 0x3, 0xe6, 0xc0, 0xf7, 0x13, 0xab, 0x85, 0xd9, 0x41, 0x7a, 0xa8, 0xcf, + 0x58, 0x74, 0xb, 0x78, 0x7f, 0x4, 0x4d, 0xf, 0x2, 0xda, 0xea, 0x97, + 0x82, 0xb2, 0x0, 0x76, 0x49, 0xe8, 0x21, 0x1b, 0x70, 0x28, 0xea, 0x8a, + 0xce, 0x79, 0xbb, 0x16, 0x93, 0x4, 0x23, 0xaf, 0x90, 0x2c, 0x1c, 0xc8, + 0xf9, 0x2e, 0xd3, 0xb6, 0xc7, 0xf1, 0x6e, 0xde, 0xf7, 0x16, 0x6, 0x2b, + 0xd8, 0x90, 0x58, 0xa, 0x74, 0x0, 0xf2, 0x3d, 0xf8, 0x4d, 0x97, 0x74, + 0x84, 0x8f, 0x40, 0xc9, 0xec, 0x86, 0x48, 0x40, 0xcb, 0x13, 0x22, 0xd9, + 0xad, 0x69, 0x9b, 0x4e, 0x54, 0x2c, 0xa1, 0xcf, 0x5c, 0x8d, 0x8f, 0xb5, + 0xb2, 0xb4, 0x4a, 0xa2, 0x1e, 0x44, 0x93, 0x38, 0x2d, 0x90, 0x2e, 0x8, + 0xab, 0x46, 0xde, 0x89, 0xb5, 0xb0, 0xed, 0xc0, 0xe5, 0xe8, 0x33, 0xdd, + 0x69, 0x5b, 0xa2, 0xce, 0x9c, 0xd2, 0x9f, 0xb2, 0x71, 0xfc, 0xf3, 0x67, + 0x9f, 0x98, 0x48, 0x34, 0x34, 0xf, 0x86, 0xe7, 0xa8, 0xbe, 0xf5, 0x50, + 0x1c, 0xae, 0x77, 0xf7, 0x81, 0x56, 0x6e, 0x41, 0x21, 0x3e, 0xf0, 0x9c, + 0x46, 0x34, 0x8d, 0x6, 0x9, 0x27, 0xe5, 0x53, 0x85, 0x59, 0x29, 0x38, + 0x9f, 0x54, 0x23, 0x7, 0x5f, 0x1d, 0xcb, 0xbb, 0x33, 0xf1, 0x44, 0xef, + 0xc, 0x3, 0x77, 0xa1, 0x37, 0x54, 0xc0, 0x4a, 0x8, 0xb0, 0x1c, 0x33, + 0x7b, 0xb, 0x72, 0x74, 0xac, 0x8d, 0x58, 0x4a, 0x20, 0xdd, 0x9e, 0x5d, + 0xd4, 0xf8, 0x4, 0x75, 0xd8, 0x24, 0x65, 0xb0, 0x60, 0x49, 0x4, 0xa0, + 0x28, 0x50, 0xb4, 0xd5, 0xcd, 0xc8, 0xc1, 0xdf, 0xf8, 0x26, 0x38, 0x26, + 0x82, 0xa1, 0xf2, 0xc7, 0x69, 0xcb, 0xf1, 0xa5, 0x21, 0xd4, 0x14, 0x99, + 0xa5, 0x9a, 0x59, 0x43, 0x15, 0x1c, 0x4e, 0x66, 0x1, 0x5a, 0x1a, 0x9b, + 0xbe, 0x82, 0x22, 0x43, 0x5b, 0xd, 0x22, 0xcf, 0x59, 0xa6, 0xc8, 0x4, + 0x11, 0x23, 0xc6, 0xc, 0xc7, 0x5, 0x8d, 0x4d, 0x19, 0xe0, 0x4e, 0x0, + 0x88, 0xe1, 0x3e, 0xc7, 0x39, 0xd, 0xf7, 0xab, 0x2c, 0x32, 0x2c, 0x83, + 0x91, 0xc, 0x32, 0x83, 0x4, 0x82, 0xe5, 0x79, 0x30, 0xb, 0xda, 0x60, + 0xfb, 0xe9, 0xef, 0x42, 0x48, 0x21, 0x58, 0x46, 0x8, 0x42, 0x40, 0xd7, + 0x92, 0xd7, 0x25, 0x32, 0xbe, 0x6f, 0xc9, 0x6e, 0xf, 0x2c, 0xa2, 0x9f, + 0x93, 0x86, 0xb4, 0xbf, 0xcc, 0x95, 0xf, 0x8c, 0xc3, 0xaa, 0xf5, 0x13, + 0xb0, 0x39, 0x31, 0xc4, 0xbc, 0xaa, 0x86, 0x1b, 0x6d, 0xbe, 0xbd, 0xd1, + 0xfb, 0x45, 0x1, 0x81, 0xda, 0x90, 0xa8, 0x24, 0xe2, 0x64, 0x47, 0xe4, + 0x11, 0x5c, 0x9a, 0xc0, 0x8b, 0x34, 0xf2, 0x8, 0xe2, 0xe5, 0xad, 0x31, + 0xff, 0xb9, 0x50, 0x9b, 0xe6, 0x0, 0xc9, 0xf5, 0x84, 0x1a, 0x9b, 0x6f, + 0xf6, 0xea, 0xb3, 0x1e, 0x21, 0x6b, 0xb0, 0xb, 0x1c, 0x66, 0x56, 0x5f, + 0x12, 0x7, 0xab, 0x5c, 0xc8, 0xcf, 0xc3, 0xad, 0x66, 0xb9, 0x68, 0x48, + 0x1b, 0x24, 0x39, 0xa4, 0x65, 0xd4, 0xa3, 0x73, 0x82, 0xc3, 0x8, 0x45, + 0xda, 0x1, 0xbb, 0x2a, 0x68, 0x41, 0xa6, 0x29, 0x28, 0x99, 0x7f, 0x9e, + 0xf0, 0x48, 0xe, 0xe1, 0xef, 0xb1, 0x9a, 0xc3, 0x9d, 0xd2, 0xce, 0x5c, + 0xcf, 0x7c, 0xc3, 0xdb, 0x30, 0x48, 0xeb, 0xc1, 0x51, 0x46, 0x2e, 0x41, + 0x37, 0xe2, 0x6a, 0x23, 0x44, 0xec, 0x22, 0xfc, 0xfc, 0xbd, 0xbc, 0x67, + 0xd3, 0x25, 0x74, 0xd9, 0x42, 0x8a, 0x6a, 0x45, 0xf4, 0x5, 0xaa, 0x5f, + 0x83, 0x93, 0xf, 0x36, 0x65, 0x34, 0xdf, 0xa4, 0x2e, 0x8f, 0x37, 0x6, + 0xf0, 0x97, 0x3d, 0x2f, 0xd8, 0x95, 0x5b, 0xd4, 0xdb, 0xa5, 0x27, 0xa4, + 0x6e, 0xc3, 0xf, 0xb5, 0xa0, 0xa2, 0x6d, 0x61, 0x58, 0x11, 0xe6, 0xed, + 0x9a, 0x1b, 0x31, 0x28, 0xa0, 0xdb, 0x9, 0x22, 0x5f, 0x14, 0xbc, 0xd5, + 0xe9, 0x2d, 0x1, 0xd3, 0x11, 0xf0, 0x4b, 0xb8, 0x14, 0x13, 0x72, 0x5d, + 0xb3, 0xb5, 0x89, 0x54, 0xbf, 0xf4, 0x2a, 0xb6, 0xe6, 0x29, 0xbf, 0xb6, + 0xe1, 0xf0, 0xdb, 0x4a, 0x9a, 0x9b, 0xa6, 0x45, 0xb3, 0x1e, 0xcf, 0xfb, + 0x43, 0x44, 0xa1, 0xb0, 0xe2, 0xb1, 0xc0, 0x9e, 0xbd, 0x45, 0x29, 0x5c, + 0xba, 0xb7, 0x84, 0xe1, 0xf2, 0xa5, 0x3c, 0x92, 0x66, 0xdb, 0xd1, 0xb6, + 0x21, 0xce, 0x2b, 0x81, 0xd8, 0x5e, 0xec, 0x6d, 0x58, 0xcc, 0x54, 0x6f, + 0x3d, 0xaa, 0x1b, 0xf4, 0xe4, 0x5f, 0x16, 0x87, 0x7, 0x90, 0xe1, 0xa7, + 0x1f, 0xbc, 0xd, 0x8c, 0xf7, 0xd9, 0x0, 0x86, 0x2, 0xcb, 0xcb, 0xce, + 0x17, 0x85, 0xe9, 0xe6, 0x90, 0x5a, 0x12, 0xc6, 0xb4, 0x44, 0xac, 0xf8, + 0x86, 0xe0, 0x8d, 0xd7, 0x62, 0x69, 0x27, 0x3e, 0x28, 0x69, 0x58, 0x3c, + 0x8f, 0xfd, 0x53, 0xac, 0xda, 0x63, 0xa6, 0x47, 0x72, 0x5a, 0x2b, 0x9c, + 0x17, 0xc, 0xd1, 0xd6, 0x8f, 0xf7, 0xbb, 0x67, 0x45, 0xc8, 0x91, 0x98, + 0xa5, 0x40, 0xb4, 0x9b, 0xe7, 0x82, 0xdc, 0x96, 0x59, 0x64, 0x4d, 0x83, + 0xb1, 0xee, 0x27, 0xe4, 0x3f, 0xe6, 0x87, 0xd3, 0xf1, 0xde, 0x23, 0xdd, + 0x19, 0x46, 0x87, 0xce, 0x4e, 0xb, 0x3a, 0x61, 0x72, 0x7f, 0x2b, 0x4d, + 0xa2, 0xe9, 0x13, 0x37, 0x33, 0x51, 0x91, 0x52, 0xbe, 0x53, 0x48, 0x52, + 0x70, 0x25, 0xf2, 0xd8, 0x66, 0x3c, 0x4e, 0xbe, 0x34, 0xba, 0xc4, 0xf7, + 0x39, 0x9, 0x91, 0x4c, 0x2b, 0x9a, 0x35, 0xef, 0x4c, 0xb9, 0x11, 0x7d, + 0xdb, 0x4f, 0xfc, 0xc1, 0xfa, 0xbb, 0x10, 0xed, 0xa0, 0xda, 0x8d, 0x5d, + 0x2c, 0x36, 0x7c, 0xd7, 0x32, 0xa1, 0x3c, 0xa0, 0x6b, 0xbe, 0x7b, 0xd7, + 0x1, 0xa, 0x72, 0xa9, 0xd0, 0xcb, 0x27, 0x16, 0x68, 0xa7, 0x52, 0xd7, + 0xf9, 0xf4, 0xb0, 0xac, 0xdd, 0x70, 0x19, 0xd9, 0xca, 0x37, 0x9e, 0x44, + 0x6c, 0xc5, 0x12, 0x43, 0x46, 0x7f, 0x9c, 0xd6, 0xce, 0x99, 0x89, 0xea, + 0xc2, 0x91, 0x5b, 0x92, 0x7c, 0x62, 0x39, 0xbe, 0x64, 0x91, 0x69, 0x94, + 0xc9, 0x90, 0x61, 0x54, 0xa6, 0x36, 0xa3, 0xec, 0x67, 0x80, 0xb0, 0x56, + 0x87, 0xda, 0xb9, 0xe1, 0xbd, 0x38, 0x7a, 0xec, 0x3a, 0x3, 0xe3, 0xf9, + 0x1b, 0x2e, 0x42, 0x9e, 0x4c, 0x58, 0x8b, 0x21, 0x1b, 0xd5, 0xef, 0x87, + 0x32, 0x68, 0xde, 0x60, 0xd1, 0x31, 0xf8, 0x80, 0x37, 0xac, 0x77, 0x7f, + 0x7f, 0x33, 0xcb, 0xe8, 0x9b, 0x9f, 0xfe, 0xcb, 0x8b, 0xef, 0xdc, 0x10, + 0xd4, 0x4e, 0x8c, 0x37, 0xf8, 0xe1, 0x7f, 0x3f, 0xc6, 0x56, 0x9c, 0xe9, + 0x7f, 0x91, 0x10, 0x61, 0x1f, 0xf1, 0x38, 0x20, 0xf9, 0xe3, 0x30, 0x54, + 0xcb, 0x48, 0xc4, 0xd0, 0xc, 0x68, 0xc1, 0xfe, 0xb1, 0xdb, 0xb2, 0xa2, + 0xa5, 0x9d, 0x4e, 0xb2, 0x74, 0x51, 0x9d, 0x5a, 0x5d, 0xec, 0x7c, 0x60, + 0x9d, 0xe, 0x30, 0x92, 0x65, 0xa4, 0xf2, 0x8c, 0x31, 0xd2, 0x4, 0x18, + 0xa9, 0x63, 0xf1, 0xfa, 0x23, 0x93, 0xe, 0x84, 0x98, 0xc8, 0x40, 0x67, + 0x45, 0x3a, 0x42, 0xe5, 0x58, 0x85, 0xf2, 0x57, 0xaa, 0xbc, 0xbe, 0x16, + 0x1d, 0x88, 0x21, 0x6e, 0x5, 0xf9, 0x8e, 0x4a, 0xb7, 0x90, 0xb5, 0x58, + 0x1d, 0xe1, 0xb5, 0x31, 0x73, 0x72, 0xb9, 0x8c, 0xc1, 0x9a, 0xec, 0x62, + 0xec, 0xeb, 0xa7, 0xf2, 0x64, 0xfb, 0x14, 0xbe, 0xae, 0x48, 0xee, 0xa, + 0x4c, 0x82, 0x98, 0x7f, 0x2f, 0x5c, 0x66, 0xd0, 0x51, 0x8d, 0xe0, 0x22, + 0x47, 0x11, 0x70, 0x73, 0x6b, 0xee, 0x41, 0x4e, 0x59, 0xac, 0x41, 0x44, + 0xd5, 0x38, 0x95, 0xc9, 0x7, 0xfb, 0x42, 0x11, 0xf5, 0x74, 0x58, 0xb, + 0x34, 0x5e, 0xfa, 0x7, 0x42, 0x44, 0x4e, 0xf3, 0x53, 0x1f, 0x7, 0x2e, + 0x16, 0x34, 0x72, 0xf4, 0xe4, 0x43, 0x86, 0x4b, 0xef, 0x29, 0x5, 0x31, + 0x29, 0x61, 0xf7, 0x9d, 0x64, 0x96, 0x60, 0x8a, 0x34, 0x3, 0xb6, 0x7d, + 0x2f, 0x97, 0x9c, 0x82, 0x8f, 0xc0, 0xd1, 0xb7, 0xa4, 0x5d, 0x84, 0xf7, + 0xbd, 0xc2, 0x95, 0xe8, 0xdf, 0x37, 0xfb, 0x28, 0x62, 0x8c, 0x7a, 0xc9, + 0x46, 0x2f, 0x8, 0xca, 0x19, 0xcd, 0x66, 0x14, 0xe4, 0xc6, 0x7f, 0x86, + 0xe0, 0xf0, 0xf8, 0x79, 0xdd, 0xb2, 0x4e, 0xfa, 0x15, 0x6d, 0xfc, 0xb7, + 0xf0, 0xbe, 0x99, 0x1b, 0xd8, 0xba, 0x9a, 0xd, 0xf8, 0xc8, 0x12, 0xb8, + 0x75, 0xb4, 0xf1, 0xe9, 0x94, 0xf9, 0x45, 0x33, 0xb1, 0x3, 0x52, 0x18, + 0x95, 0x4d, 0x8c, 0x9a, 0xa5, 0x6d, 0x68, 0x52, 0x66, 0x73, 0x4f, 0x5a, + 0x86, 0x95, 0x8e, 0x86, 0x40, 0x4f, 0x31, 0x94, 0x80, 0xf8, 0x77, 0x98, + 0x70, 0xb7, 0x53, 0x17, 0x7f, 0x57, 0x7e, 0xb2, 0xb2, 0x41, 0x39, 0x40, + 0xbf, 0x69, 0xe5, 0xf3, 0xd, 0xb0, 0x61, 0x91, 0x25, 0xd0, 0x77, 0x20, + 0x1f, 0x7a, 0x46, 0x54, 0xc6, 0xc5, 0xea, 0x41, 0xa7, 0xa0, 0x2a, 0x60, + 0x63, 0x47, 0x83, 0xc1, 0xa, 0xf5, 0x54, 0x26, 0x97, 0x9b, 0xc3, 0xc6, + 0x9a, 0xc8, 0xa8, 0xf0, 0x41, 0xff, 0xab, 0xa0, 0xb4, 0xae, 0x8c, 0xe, + 0xdc, 0xc0, 0xd0, 0x1a, 0xfb, 0x11, 0xbb, 0x7a, 0xd8, 0x9d, 0x29, 0xf5, + 0x18, 0x43, 0x68, 0x26, 0x94, 0xb3, 0xf8, 0xab, 0xe4, 0xae, 0x7c, 0x2c, + 0xe1, 0x75, 0xc1, 0x80, 0x28, 0xda, 0x7, 0xf4, 0xd9, 0xbf, 0x42, 0xb6, + 0xae, 0xef, 0xdd, 0x6f, 0x6c, 0xad, 0x10, 0x7c, 0x83, 0x98, 0x36, 0xaf, + 0x91, 0xed, 0xc9, 0x53, 0xc2, 0xaf, 0x90, 0x8f, 0x22, 0x1a, 0x43, 0xfb, + 0x8f, 0x94, 0xca, 0xcd, 0x7d, 0xdb, 0xd2, 0xfe, 0xbf, 0x6f, 0x7d, 0x3e, + 0x99, 0x79, 0x3, 0x31, 0xef, 0x4, 0xef, 0x16, 0x39, 0xaf, 0xd4, 0x6a, + 0xd3, 0x42, 0x50, 0x2f, 0x4c, 0x78, 0xa7, 0xdc, 0x18, 0xa, 0x7b, 0x63, + 0x62, 0xd1, 0x1e, 0x86, 0x84, 0x8e, 0xba, 0x19, 0xd2, 0x0, 0x4a, 0xe5, + 0x61, 0x11, 0xe6, 0x62, 0x78, 0x54, 0x7c, 0x68, 0x2b, 0xde, 0x98, 0xff, + 0x4, 0x93, 0x37, 0xb5, 0x48, 0xcc, 0x8c, 0x7d, 0xd7, 0xd9, 0x38, 0xff, + 0xc0, 0x92, 0x78, 0x55, 0x7e, 0xc4, 0x27, 0x30, 0x8b, 0xaf, 0x1b, 0x16, + 0xb8, 0x6f, 0xf9, 0xe7, 0x9e, 0x35, 0xe5, 0x6b, 0xd0, 0xaa, 0xfa, 0x70, + 0xd8, 0x1e, 0xb6, 0x90, 0xa7, 0xb2, 0xd9, 0x7d, 0xca, 0x56, 0x5c, 0x2c, + 0x9a, 0xca, 0x32, 0x7c, 0x19, 0x14, 0x39, 0xf, 0x13, 0x1d, 0x87, 0x47, + 0x61, 0x9, 0x61, 0xa4, 0x2b, 0x34, 0x38, 0x5a, 0x10, 0x99, 0xa6, 0x14, + 0x42, 0x7, 0xec, 0xe3, 0x25, 0x88, 0x63, 0x10, 0xef, 0xef, 0x56, 0x1, + 0x82, 0x53, 0xe, 0xbc, 0x42, 0xd7, 0x68, 0x36, 0x33, 0x9, 0xcc, 0x88, + 0xa7, 0x72, 0xe, 0xbb, 0x77, 0xe5, 0xbe, 0x2a, 0xe8, 0x4e, 0x72, 0x2e, + 0x24, 0xd2, 0xea, 0xa9, 0xb0, 0x12, 0xa7, 0x21, 0x9, 0x17, 0x22, 0x74, + 0x7f, 0xa8, 0x4, 0xae, 0x82, 0x8a, 0x28, 0x68, 0x72, 0xb9, 0xfe, 0xbc, + 0xaf, 0x25, 0x64, 0xb6, 0x3f, 0x5d, 0x14, 0x6b, 0xef, 0x45, 0x83, 0xec, + 0xf1, 0xaa, 0xf1, 0x2d, 0x1b, 0x9b, 0xd6, 0xee, 0x4b, 0xb4, 0x87, 0xc3, + 0xac, 0xcb, 0x6, 0x57, 0xc5, 0xf0, 0xd8, 0xf4, 0x9a, 0xb7, 0x48, 0x9, + 0x65, 0xfa, 0x51, 0x6b, 0xbc, 0xee, 0x4d, 0xe6, 0x10, 0xd2, 0xd2, 0x4f, + 0x13, 0x14, 0xf1, 0x47, 0x3, 0xf2, 0xf9, 0x61, 0xf4, 0x8a, 0x66, 0x21, + 0x44, 0x28, 0x28, 0xc7, 0x70, 0x6b, 0x71, 0xa3, 0xc6, 0xf6, 0x64, 0xdc, + 0x4a, 0xbc, 0xde, 0x73, 0xe1, 0x48, 0x9d, 0xb4, 0x98, 0x54, 0x3b, 0x18, + 0xe0, 0xa7, 0x89, 0x43, 0xd4, 0x85, 0x36, 0xb5, 0x2a, 0x96, 0x52, 0x67, + 0x3e, 0x26, 0x23, 0xb3, 0xc4, 0x34, 0xe, 0x5, 0xf0, 0x6c, 0xdf, 0xc9, + 0x4c, 0x60, 0x5f, 0x8e, 0x5e, 0x50, 0xef, 0x16, 0x14, 0xdc, 0x70, 0x40, + 0x9, 0xb4, 0x73, 0xcd, 0x16, 0x90, 0x91, 0x82, 0x24, 0x4a, 0x16, 0x79, + 0x56, 0x15, 0xc6, 0x2c, 0xb3, 0xb9, 0x17, 0x7d, 0xd1, 0xff, 0xd4, 0xfd, + 0xcb, 0x7d, 0xc2, 0x24, 0xee, 0x56, 0x83, 0x55, 0x17, 0xd8, 0x5e, 0xab, + 0xe1, 0xdd, 0x3a, 0x51, 0x74, 0x71, 0x81, 0x57, 0xe7, 0x26, 0xcf, 0x3d, + 0x9c, 0x47, 0x7, 0xe8, 0xcc, 0xa8, 0x59, 0xe, 0x86, 0x7, 0x91, 0xbe, + 0x7a, 0x52, 0x3b, 0xe4, 0x40, 0x22, 0x93, 0xd3, 0x31, 0x26, 0x9f, 0x24, + 0x60, 0x4, 0x2d, 0x62, 0x90, 0x3e, 0xfb, 0xc2, 0xd9, 0x66, 0xdf, 0x39, + 0xab, 0xc7, 0xeb, 0x21, 0xb8, 0x95, 0x2b, 0xd3, 0x2c, 0x53, 0xac, 0x99, + 0x83, 0x1f, 0x73, 0x7a, 0xab, 0xaf, 0x97, 0x95, 0x88, 0x8e, 0xad, 0x8, + 0xa3, 0x39, 0xdc, 0x5e, 0x30, 0x60, 0x1c, 0x44, 0xdf, 0xa7, 0x7c, 0x26, + 0xfa, 0x3b, 0xf, 0xac, 0x24, 0xb1, 0xc3, 0xc4, 0xcf, 0x7, 0xdf, 0xee, + 0x91, 0x2c, 0x77, 0x97, 0x59, 0x9d, 0xf8, 0x82, 0x83, 0x3, 0x7, 0xf1, + 0xda, 0xe5, 0xe, 0x4a, 0xe7, 0x2a, 0x25, 0x31, 0x51, 0x84, 0x89, 0xcd, + 0x9e, 0xe9, 0xeb, 0x56, 0xe2, 0x21, 0x70, 0x61, 0x1b, 0x14, 0x62, 0x58, + 0x62, 0xd3, 0xde, 0x68, 0x3b, 0xa8, 0x62, 0x46, 0x76, 0x2, 0x86, 0x77, + 0x61, 0xfa, 0x63, 0xc2, 0x17, 0x4b, 0x28, 0xb6, 0xaf, 0x51, 0xd5, 0x6b, + 0x5b, 0x77, 0x27, 0x5b, 0x9a, 0x24, 0x39, 0xcd, 0x9f, 0xf, 0xad, 0x99, + 0x14, 0x4e, 0x3b, 0xfb, 0x3b, 0xad, 0x74, 0xdc, 0xcf, 0x43, 0xd7, 0xa1, + 0x4, 0x19, 0x57, 0x7e, 0x1f, 0xcf, 0xc7, 0x23, 0xb, 0x41, 0x78, 0x67, + 0x66, 0xb1, 0x8c, 0x3a, 0x47, 0xb2, 0x36, 0xe, 0x86, 0x56, 0xc9, 0x21, + 0xfb, 0xa3, 0xf3, 0x20, 0xc3, 0x63, 0x3f, 0x63, 0xef, 0x1f, 0x33, 0xb, + 0x31, 0xb9, 0xf2, 0x0, 0xef, 0xe, 0xd5, 0xf9, 0x17, 0x44, 0x79, 0xc7, + 0x3b, 0xf1, 0x19, 0x64, 0xee, 0xc0, 0xeb, 0x71, 0xfd, 0xce, 0xe7, 0x8c, + 0x5f, 0x90, 0xb1, 0x35, 0x37, 0xaf, 0x53, 0x5e, 0x2b, 0xef, 0xc8, 0x1e, + 0xf0, 0xc0, 0x3f, 0x1b, 0xc, 0xf4, 0xb8, 0x35, 0xb9, 0x98, 0x93, 0x4d, + 0x6d, 0x4c, 0xe2, 0x88, 0x86, 0x26, 0x10, 0x37, 0xd0, 0x34, 0xc9, 0xc0, + 0x73, 0x3f, 0xa1, 0xaa, 0xf7, 0x93, 0xb, 0xe, 0x52, 0x30, 0x79, 0x35, + 0x3e, 0x8f, 0x11, 0xe1, 0x8d, 0xe4, 0x1a, 0x94, 0xbc, 0x44, 0x2c, 0x26, + 0xcc, 0x1a, 0x26, 0x71, 0xf, 0xb6, 0xb1, 0xf7, 0x6, 0xaf, 0x86, 0xde, + 0xad, 0x64, 0x88, 0x1c, 0x43, 0xae, 0xf6, 0xc6, 0x58, 0x42, 0x9b, 0xa0, + 0x3a, 0x2c, 0xc9, 0x6e, 0x87, 0x87, 0x54, 0xe8, 0x95, 0x2, 0x1b, 0x61, + 0x6, 0x65, 0xee, 0x9, 0x87, 0x7f, 0xed, 0x2d, 0xd7, 0x64, 0x4f, 0x4, + 0x49, 0x75, 0x54, 0x2c, 0x9a, 0xdb, 0xa5, 0x6e, 0xf9, 0x37, 0xea, 0x10, + 0x86, 0x31, 0x5f, 0xf5, 0x7a, 0xfa, 0x51, 0xe6, 0x5d, 0xd0, 0xc, 0x2b, + 0xf2, 0xe5, 0x2, 0x35, 0xa8, 0x2c, 0xb, 0xdb, 0x56, 0xcb, 0x41, 0x12, + 0x34, 0xe4, 0xee, 0x49, 0x87, 0x80, 0x6, 0x1d, 0x89, 0x22, 0x87, 0xea, + 0xf4, 0x54, 0x3d, 0xa, 0xc7, 0xcf, 0xc6, 0xd, 0xf1, 0x1b, 0xa3, 0xb7, + 0x50, 0x54, 0x4f, 0x8e, 0x20, 0xc7, 0x1, 0x1d, 0x78, 0x78, 0x12, 0x1e, + 0x6f, 0x3a, 0x71, 0x23, 0xa2, 0x25, 0x5c, 0x57, 0xb0, 0x73, 0xe8, 0x16, + 0x3c, 0xca, 0x7c, 0x75, 0x11, 0x81, 0x4a, 0xdb, 0xfa, 0x6c, 0xf, 0xe2, + 0x24, 0x5a, 0x83, 0x5d, 0x73, 0xe9, 0x24, 0x27, 0x84, 0x65, 0x82, 0xf2, + 0x8a, 0x79, 0x80, 0xee, 0x44, 0x55, 0xca, 0x1, 0xae, 0xda, 0xa5, 0xa8, + 0x72, 0x5, 0x4f, 0xad, 0x57, 0x68, 0x2b, 0xf6, 0xac, 0x16, 0xd6, 0xeb, + 0x99, 0x47, 0xa, 0x34, 0x3a, 0x88, 0x9, 0x49, 0x80, 0xcf, 0x78, 0xbc, + 0xbe, 0x19, 0xc2, 0x71, 0xb1, 0x73, 0xdf, 0xac, 0x10, 0x80, 0x7e, 0x30, + 0x63, 0x2c, 0xe8, 0x91, 0x5, 0x33, 0x29, 0xc5, 0x7c, 0xa1, 0xf5, 0x74, + 0xca, 0x2b, 0x87, 0x7e, 0xeb, 0xbb, 0x46, 0x89, 0x5a, 0xc7, 0x53, 0x19, + 0xfb, 0xf6, 0x82, 0x15, 0x28, 0x98, 0x2, 0x9b, 0x12, 0x15, 0xab, 0x6b, + 0x7f, 0x8d, 0x15, 0xf8, 0x84, 0x6a, 0x4b, 0x74, 0x6f, 0xff, 0x85, 0x55, + 0x1a, 0x61, 0xe8, 0x8, 0xff, 0xd0, 0x26, 0xbf, 0x30, 0xa5, 0x85, 0xaf, + 0x51, 0xd, 0xf1, 0x17, 0x2c, 0xbb, 0x41, 0x2f, 0x4, 0x2d, 0x9e, 0xe2, + 0xb6, 0x14, 0x9f, 0xbb, 0x3f, 0x92, 0x3a, 0x70, 0x9d, 0xf2, 0xa0, 0x71, + 0x1c, 0x4d, 0x88, 0xb1, 0xfa, 0xc0, 0x21, 0x55, 0xbb, 0x5c, 0x16, 0xf9, + 0x42, 0x51, 0x75, 0xe, 0x95, 0x8f, 0x8d, 0x26, 0x45, 0x90, 0xcb, 0xd8, + 0x10, 0xed, 0x1f, 0x91, 0x7e, 0x7a, 0x84, 0xf1, 0xec, 0x3d, 0xe2, 0x85, + 0xfe, 0xd5, 0x7c, 0x46, 0x8c, 0x46, 0xc7, 0xc5, 0x41, 0xae, 0xc, 0xb7, + 0xf8, 0x42, 0x95, 0xce, 0x6d, 0x2b, 0xe5, 0x7e, 0x3d, 0x15, 0xa2, 0x46, + 0x24, 0xb4, 0x3, 0xfc, 0xe5, 0xf0, 0x6f, 0x16, 0xbc, 0xaf, 0x3b, 0x35, + 0x26, 0x7c, 0x7b, 0x8f, 0x20, 0x83, 0x1a, 0xd4, 0xe2, 0x25, 0xc1, 0x6c, + 0x28, 0x7e, 0x0, 0x94, 0xa1, 0x68, 0xc2, 0x31, 0x50, 0x8, 0x5f, 0xb8, + 0x48, 0x7a, 0xa8, 0xbd, 0xf6, 0x42, 0xfd, 0x72, 0xe2, 0x4, 0x6a, 0x1d, + 0xde, 0x2f, 0x59, 0x2f, 0x56, 0x21, 0x13, 0xa0, 0xb0, 0x39, 0xc2, 0xeb, + 0xfd, 0x0, 0xa1, 0x89, 0x38, 0xb9, 0x80, 0x8e, 0x51, 0x63, 0x9d, 0x32, + 0x57, 0xc1, 0xd0, 0x9b, 0xf6, 0xfa, 0x23, 0xa, 0xcd, 0x2d, 0x38, 0x5e, + 0x3a, 0xb1, 0xfe, 0x45, 0x7a, 0xfe, 0xef, 0x96, 0xf3, 0x97, 0x90, 0x2b, + 0x44, 0xe9, 0x4, 0xd6, 0xd0, 0xd4, 0xe1, 0x24, 0xcb, 0x3d, 0x7b, 0x7a, + 0x83, 0x7, 0xa8, 0xf4, 0x13, 0xa, 0xd, 0xb0, 0xe5, 0xf6, 0xd6, 0x78, + 0x5, 0xe5, 0x9c, 0xef, 0x12, 0xa9, 0xd1, 0x77, 0xd4, 0x16, 0x60, 0xc0, + 0xf0, 0x49, 0x8c, 0xe5, 0x98, 0xa5, 0x5b, 0xb1, 0xc9, 0x86, 0xf0, 0xe, + 0x9c, 0x5a, 0xc2, 0xd7, 0x65, 0x91, 0x54, 0xf6, 0x2c, 0x96, 0x31, 0xf7, + 0x89, 0x65, 0xb, 0xed, 0x8, 0xa6, 0x25, 0x29, 0x39, 0x2a, 0x28, 0x31, + 0x22, 0x96, 0x27, 0x97, 0x35, 0xbc, 0x93, 0x25, 0x71, 0x45, 0x78, 0x93, + 0x87, 0x9, 0x13, 0x58, 0x9d, 0x10, 0xdd, 0xa0, 0x93, 0x24, 0xb2, 0xac, + 0xbc, 0x36, 0xa2, 0x97, 0x57, 0xb9, 0xad, 0xcf, 0x26, 0x7c, 0x14, 0x1c, + 0x57, 0x5c, 0x1c, 0x6, 0x65, 0x6, 0xdb, 0x8e, 0xae, 0xd3, 0x65, 0xb7, + 0x15, 0xe4, 0x46, 0xb1, 0xd5, 0x28, 0xdb, 0x17, 0x90, 0xe8, 0xd, 0x47, + 0xde, 0x21, 0x48, 0xc5, 0xc6, 0x18, 0x63, 0xe2, 0x3e, 0x41, 0x4e, 0x7a, + 0x82, 0xab, 0x30, 0xa4, 0x24, 0xe5, 0x56, 0xee, 0x4c, 0x4c, 0x50, 0x13, + 0x95, 0xc, 0xb2, 0x5e, 0x5f, 0xb9, 0xf5, 0x4e, 0x3, 0xad, 0xb7, 0x11, + 0xbf, 0x3f, 0x9, 0x70, 0x5a, 0xf0, 0xad, 0x60, 0xb9, 0xef, 0xf9, 0xbc, + 0xf4, 0xf4, 0xea, 0xd2, 0xb8, 0x53, 0x9, 0xac, 0xf7, 0xcf, 0xa8, 0x7d, + 0x77, 0x1c, 0xe5, 0x23, 0x9b, 0xb4, 0x35, 0xb9, 0x46, 0xc9, 0x7a, 0x7f, + 0x41, 0x18, 0xb2, 0x24, 0xdf, 0x7a, 0x9a, 0xef, 0xa9, 0xb8, 0xab, 0x78, + 0x99, 0xbe, 0x44, 0xb5, 0x9, 0xd2, 0x58, 0xec, 0x54, 0xa6, 0x8d, 0x58, + 0xbc, 0x27, 0x3a, 0x2a, 0xb9, 0x50, 0xca, 0x23, 0xf1, 0x93, 0x5e, 0xc9, + 0x7b, 0xfd, 0x79, 0x4a, 0xf4, 0x3e, 0x2d, 0x6b, 0x44, 0xd6, 0xf6, 0x8d, + 0xfa, 0x6, 0x2e, 0xba, 0x83, 0x9a, 0xe4, 0x91, 0x5f, 0xe0, 0x73, 0x4d, + 0x64, 0x11, 0xf6, 0x6f, 0x61, 0x61, 0xee, 0xcc, 0x69, 0xbd, 0xd5, 0x80, + 0x47, 0x4b, 0xe1, 0xb2, 0x84, 0xa, 0xcb, 0xcf, 0x11, 0x62, 0xbb, 0x61, + 0xe7, 0x87, 0x34, 0x6b, 0xad, 0x4a, 0xaa, 0x23, 0xd7, 0x9, 0xaf, 0x1c, + 0xa2, 0x89, 0x14, 0x53, 0xae, 0xe2, 0x3e, 0xbe, 0xf6, 0x61, 0xe0, 0xbd, + 0x54, 0xe8, 0x7f, 0x45, 0x8e, 0x7d, 0x10, 0xb, 0x57, 0xa9, 0x60, 0xc9, + 0x38, 0x15, 0xf0, 0xc5, 0xc4, 0x44, 0x86, 0x18, 0xb6, 0x91, 0xa6, 0x53, + 0xf7, 0x3b, 0x18, 0x99, 0x4b, 0xf3, 0xea, 0xc5, 0x6e, 0xaa, 0xc9, 0x9c, + 0xe3, 0xb3, 0x33, 0xf0, 0x83, 0xb2, 0xf2, 0x7e, 0xe1, 0x88, 0xc3, 0xb1, + 0xb4, 0x14, 0x24, 0xc9, 0x3, 0xe0, 0x76, 0x4f, 0x8b, 0x53, 0xbd, 0xaf, + 0x66, 0x28, 0x9e, 0xb7, 0x95, 0x3a, 0xf5, 0xbe, 0x3a, 0xfa, 0xc9, 0x6b, + 0x29, 0xe2, 0x88, 0xee, 0x17, 0x7b, 0x9f, 0xab, 0x5c, 0x3e, 0xb5, 0xf5, + 0x9d, 0x3f, 0xc8, 0x6b, 0x67, 0xb8, 0x3e, 0xc4, 0xe1, 0xd7, 0x70, 0x7, + 0xa6, 0x84, 0x8d, 0xc5, 0x8f, 0x6d, 0x0, 0x88, 0x3c, 0xf5, 0x13, 0x9e, + 0x17, 0x9f, 0x9d, 0x2b, 0x6f, 0x4b, 0xbb, 0x23, 0xf2, 0xcb, 0x40, 0xd6, + 0xed, 0x66, 0x7b, 0xfb, 0x74, 0x59, 0x29, 0x96, 0x61, 0x3f, 0x4f, 0x6e, + 0x38, 0x91, 0x96, 0x9a, 0x98, 0x18, 0x9e, 0xc7, 0x61, 0x35, 0xa6, 0x2b, + 0xb6, 0x54, 0xe6, 0xad, 0x2e, 0xf4, 0xe1, 0x65, 0x59, 0x8f, 0x50, 0x3d, + 0x44, 0xf9, 0x88, 0x6e, 0x8, 0xde, 0x33, 0xaf, 0x7, 0x62, 0x93, 0x46, + 0xc1, 0x4a, 0x57, 0x48, 0x85, 0xf9, 0xc, 0x44, 0x53, 0x9b, 0x7e, 0xae, + 0x4e, 0x39, 0x19, 0x86, 0xff, 0x56, 0x43, 0x3b, 0xdb, 0x67, 0x97, 0xcb, + 0xec, 0x23, 0xf, 0x66, 0xf1, 0xf0, 0xb1, 0x4a, 0x4a, 0x6e, 0x27, 0x7f, + 0x57, 0xa0, 0x44, 0xb5, 0x6d, 0x86, 0xfc, 0x3b, 0xba, 0x64, 0xcf, 0xee, + 0x7c, 0xb2, 0xa0, 0x84, 0x46, 0x56, 0xfb, 0x88, 0x3f, 0xdb, 0xfa, 0x86, + 0xd1, 0xb0, 0xef, 0x31, 0xd4, 0x38, 0x98, 0x3c, 0x52, 0xd3, 0xc8, 0xb2, + 0x35, 0x62, 0x21, 0x40, 0xf6, 0xe3, 0x59, 0x68, 0x86, 0xfa, 0x19, 0x1c, + 0x4d, 0x1b, 0x83, 0xe7, 0xf7, 0x97, 0x79, 0xdd, 0x62, 0x7, 0xaa, 0xf4, + 0xc2, 0x7b, 0xb8, 0x98, 0xf0, 0xa7, 0xca, 0xa1, 0xf3, 0xe2, 0xf, 0xc7, + 0x5a, 0x63, 0x12, 0x49, 0x4a, 0xac, 0xa8, 0xec, 0x8a, 0xee, 0xdd, 0xd7, + 0x97, 0x2d, 0xf6, 0x22, 0xd7, 0x3f, 0x95, 0xac, 0x39, 0xae, 0x8e, 0x79, + 0xe9, 0x8d, 0xe8, 0x62, 0x87, 0xc9, 0x53, 0x89, 0xda, 0x21, 0x1d, 0x39, + 0x12, 0x47, 0x98, 0xca, 0xeb, 0x95, 0x81, 0x92, 0x2, 0x35, 0x10, 0xbe, + 0xbc, 0x65, 0x1, 0x91, 0xfc, 0xaf, 0xaa, 0x2a, 0x39, 0x2c, 0xd7, 0xbe, + 0xb7, 0x21, 0x1, 0xc8, 0x45, 0xb6, 0xf4, 0xa9, 0x74, 0xd5, 0x56, 0xb9, + 0xb7, 0x90, 0xdc, 0xa0, 0x47, 0xf6, 0x38, 0x51, 0xa, 0xa3, 0xc6, 0xf2, + 0x93, 0xf8, 0xa7, 0x35, 0xf0, 0x67, 0xc7, 0xd9, 0xf, 0x3, 0x8d, 0x89, + 0x46, 0xc5, 0xc, 0xbf, 0x86, 0x63, 0xf5, 0x52, 0xa5, 0xab, 0x1f, 0x6b, + 0xb0, 0xc4, 0xd1, 0xaf, 0xc9, 0xfa, 0x9c, 0x21, 0xe7, 0xf9, 0x6f, 0x97, + 0x27, 0xf, 0xe4, 0x77, 0x48, 0x99, 0xc5, 0xd3, 0x21, 0x51, 0xfd, 0xc5, + 0x9c, 0x66, 0x43, 0x5e, 0xf0, 0x1a, 0x91, 0x4e, 0xf3, 0x26, 0x2f, 0xf9, + 0x9, 0x67, 0xc4, 0x31, 0xd4, 0x2f, 0xd5, 0x71, 0xff, 0x4f, 0x81, 0xdc, + 0x46, 0xe8, 0x23, 0xda, 0xb2, 0x4, 0xfe, 0x2d, 0x1, 0x5b, 0xc7, 0x3e, + 0x7, 0x6c, 0x98, 0xa8, 0x92, 0x3d, 0x83, 0xb4, 0xfe, 0xdd, 0x8b, 0x65, + 0x5d, 0x3e, 0xe8, 0x4a, 0x66, 0xd7, 0xc7, 0x1b, 0xd9, 0x59, 0x3c, 0xa1, + 0x3, 0x66, 0x10, 0xcb, 0x83, 0x28, 0x7f, 0xbb, 0xe2, 0xcf, 0xd5, 0xdb, + 0xdf, 0xf1, 0x3c, 0xb0, 0xdc, 0x59, 0x94, 0xee, 0xf9, 0x4, 0xd, 0x3a, + 0xc3, 0xfa, 0xb, 0xc5, 0x8b, 0x5e, 0x3d, 0xf8, 0x5d, 0xd5, 0xc1, 0x6d, + 0x3c, 0xa8, 0x83, 0x60, 0xa2, 0xf7, 0x69, 0x40, 0x7d, 0xb3, 0xc1, 0x9, + 0x3d, 0x28, 0xb1, 0xd5, 0x43, 0xed, 0x5b, 0xf1, 0xdb, 0xa4, 0xe7, 0x65, + 0xd8, 0xbd, 0x68, 0xa1, 0xee, 0xab, 0x40, 0x34, 0xdd, 0xda, 0x2c, 0xe7, + 0x94, 0x8, 0x1f, 0x8f, 0x6d, 0x2c, 0xe9, 0x76, 0xbd, 0x98, 0x1, 0xeb, + 0x18, 0x4e, 0x27, 0x52, 0x6e, 0x6a, 0xd8, 0xe2, 0xbe, 0x60, 0xad, 0xcf, + 0x1d, 0x7b, 0x43, 0xd0, 0xd0, 0xbd, 0x84, 0xab, 0x72, 0x3e, 0x1f, 0x4a, + 0x69, 0xe8, 0x92, 0xf2, 0x37, 0xc4, 0xb5, 0x84, 0x6b, 0x6d, 0x4d, 0xad, + 0x26, 0x55, 0x60, 0x9, 0x94, 0xb1, 0x59, 0x8e, 0x43, 0x48, 0xff, 0xff, + 0xfa, 0xe3, 0x8a, 0x96, 0xe, 0xc9, 0x2b, 0x57, 0xec, 0x7, 0x9a, 0xd4, + 0x91, 0xd7, 0x80, 0x82, 0xa5, 0x5b, 0x55, 0xdd, 0x58, 0xff, 0x9b, 0xef, + 0x28, 0xeb, 0x35, 0xd2, 0x60, 0x53, 0xf7, 0x95, 0x2a, 0xb3, 0x2, 0xeb, + 0x19, 0x20, 0x6f, 0x62, 0x84, 0x6c, 0x8b, 0x79, 0xd0, 0xc7, 0x76, 0xef, + 0x6d, 0x70, 0xf0, 0x24, 0xad, 0xe1, 0xe3, 0x76, 0x2c, 0xe3, 0xb, 0x75, + 0x4e, 0x19, 0x21, 0x9d, 0xb9, 0x67, 0x6d, 0x34, 0xf, 0xc2, 0x4d, 0x13, + 0xc5, 0x34, 0xf6, 0xdc, 0x3c, 0xea, 0x14, 0x78, 0x79, 0x14, 0x84, 0xf5, + 0x3c, 0xfa, 0xf, 0x48, 0xe3, 0xb9, 0x9e, 0x50, 0x78, 0x94, 0x43, 0x81, + 0xeb, 0x18, 0xdc, 0x8d, 0xf7, 0x83, 0x3f, 0x95, 0xc7, 0x89, 0x6c, 0xd2, + 0x1a, 0x58, 0x4f, 0x47, 0xb8, 0x25, 0xda, 0x86, 0x93, 0xc4, 0x74, 0xfe, + 0xc1, 0xcc, 0x7b, 0x8c, 0x85, 0x5e, 0x36, 0xd, 0xe8, 0x6b, 0x5d, 0x4f, + 0x84, 0x37, 0xbb, 0x18, 0xd7, 0xcb, 0x4b, 0x65, 0x80, 0x6c, 0x94, 0xe4, + 0x1a, 0xf8, 0x28, 0xae, 0x20, 0xbd, 0x32, 0x83, 0x6f, 0xea, 0x29, 0xf2, + 0xef, 0x97, 0x52, 0x2f, 0xd, 0x18, 0x87, 0x48, 0x9a, 0xed, 0x99, 0x6e, + 0x7, 0xaa, 0x64, 0x4a, 0x62, 0xaf, 0xb7, 0xd3, 0x69, 0x90, 0xdf, 0xfb, + 0x25, 0x85, 0xcc, 0x82, 0x7e, 0x3b, 0x25, 0x55, 0x90, 0xf7, 0xef, 0x70, + 0x9f, 0x24, 0xa3, 0x32, 0xee, 0x9d, 0x14, 0xa6, 0x76, 0xec, 0x6a, 0x44, + 0xce, 0xba, 0x2a, 0x54, 0x88, 0xbd, 0x8f, 0x2c, 0x44, 0x78, 0xb4, 0xbd, + 0xd, 0xd7, 0xfe, 0xdb, 0x58, 0x82, 0xde, 0x34, 0x91, 0x3d, 0x4a, 0x13, + 0x45, 0x84, 0x21, 0x1e, 0x93, 0x0, 0xca, 0x73, 0x29, 0xf3, 0x4a, 0xdc, + 0xa7, 0xa, 0xfa, 0xa9, 0xf7, 0xd2, 0x89, 0x92, 0x35, 0x16, 0x6, 0xb3, + 0x7b, 0xed, 0xb4, 0xac, 0x27, 0xd0, 0x66, 0xd4, 0x3e, 0x22, 0xe1, 0x27, + 0xab, 0x29, 0x49, 0x91, 0xb4, 0x71, 0x12, 0x8c, 0x28, 0xd0, 0xe1, 0x71, + 0xde, 0x11, 0x89, 0x3a, 0xbf, 0x33, 0xc0, 0x28, 0x9b, 0x3a, 0x95, 0x3e, + 0xf9, 0xc, 0xe3, 0x5b, 0x7b, 0xc, 0xc2, 0xa9, 0x53, 0xed, 0x8e, 0xb0, + 0xff, 0xd, 0xc0, 0x62, 0xfc, 0x4e, 0x62, 0x6e, 0x87, 0xf9, 0x69, 0xe4, + 0x59, 0x73, 0x3c, 0x85, 0xed, 0xdf, 0x55, 0xd0, 0xcd, 0x7a, 0x6a, 0x17, + 0x2f, 0x21, 0xbc, 0xb3, 0x4d, 0xea, 0x6d, 0x12, 0xf, 0x4c, 0x14, 0xc0, + 0xf2, 0xb2, 0x5c, 0xa5, 0x70, 0x54, 0xf2, 0x51, 0xb6, 0xc7, 0xc5, 0xc9, + 0xbd, 0x13, 0x22, 0x5e, 0xd9, 0xca, 0x2a, 0x1e, 0x37, 0x4b, 0x51, 0x54, + 0x1a, 0x3c, 0xf4, 0x3d, 0x14, 0x2f, 0xee, 0x34, 0x57, 0xdf, 0x34, 0xd, + 0x4f, 0xa5, 0x30, 0x29, 0xaf, 0xfc, 0xa9, 0xf8, 0xab, 0x30, 0xeb, 0xfa, + 0xa2, 0x80, 0x7d, 0xa5, 0xf, 0xfd, 0xde, 0x32, 0x4e, 0xbc, 0x1d, 0xd2, + 0x18, 0x4b, 0x4b, 0x80, 0x89, 0x82, 0x43, 0x57, 0x8d, 0xbf, 0x5d, 0x44, + 0xb1, 0xfc, 0xbd, 0x4d, 0xe4, 0xb2, 0x3, 0x3b, 0x4f, 0x70, 0xfe, 0x7f, + 0x33, 0x44, 0x5e, 0xd, 0x46, 0x6d, 0x1f, 0xbe, 0x68, 0x5d, 0x32, 0x2e, + 0x67, 0x91, 0x8c, 0xc6, 0xa6, 0x4e, 0x61, 0xf4, 0x4d, 0x9a, 0xac, 0x90, + 0x71, 0x55, 0x99, 0xb6, 0x9, 0x52, 0x9f, 0x2f, 0xaf, 0x2c, 0x75, 0x51, + 0x20, 0xbf, 0x6c, 0x75, 0xc2, 0x64, 0x51, 0xb8, 0x92, 0x8a, 0xd4, 0x23, + 0xeb, 0xe3, 0xbf, 0xef, 0x2e, 0xad, 0x83, 0x6d, 0x62, 0x77, 0x1f, 0x78, + 0xcb, 0xc3, 0xed, 0x17, 0xc2, 0x2c, 0x2f, 0xf8, 0x3f, 0xa2, 0xb0, 0xf6, + 0x62, 0xe8, 0x27, 0xd, 0x57, 0xb5, 0x1f, 0x68, 0x8f, 0xd4, 0xad, 0x89, + 0x11, 0x42, 0xb9, 0x26, 0x4c, 0xbe, 0x8e, 0x38, 0x6b, 0x55, 0xb3, 0x4b, + 0xfb, 0x6, 0xb6, 0xa3, 0x84, 0x2d, 0xa4, 0x90, 0x1, 0xae, 0x1a, 0xed, + 0xab, 0xa1, 0x5b, 0x48, 0x59, 0x32, 0x10, 0xb1, 0xb5, 0x39, 0x54, 0xc5, + 0xc0, 0xc5, 0x7f, 0xa0, 0x26, 0x1e, 0xee, 0x85, 0x76, 0x48, 0xd8, 0xc7, + 0x1a, 0x4a, 0x6c, 0x99, 0xed, 0x7c, 0xf6, 0x51, 0x6b, 0x3a, 0x64, 0x98, + 0xcb, 0xac, 0x5f, 0x11, 0xb0, 0xfe, 0x63, 0xbc, 0x2e, 0x9a, 0x93, 0x12, + 0xb5, 0xfa, 0x5c, 0x5a, 0x28, 0x84, 0x30, 0xb7, 0x75, 0x23, 0x8a, 0x87, + 0xed, 0x64, 0x3d, 0xd4, 0xe6, 0x9e, 0x57, 0x44, 0xbc, 0x9c, 0x66, 0x8, + 0x3f, 0x11, 0xa7, 0x1d, 0xdb, 0x90, 0x6c, 0xa2, 0x38, 0x30, 0x42, 0xa7, + 0xfb, 0xca, 0x44, 0x16, 0x5a, 0x2e, 0x64, 0x2e, 0xa0, 0xf6, 0xfb, 0x30, + 0x8a, 0x1f, 0x38, 0x9c, 0xca, 0xb6, 0x53, 0xb, 0x36, 0x2a, 0x8f, 0xee, + 0xaf, 0x3f, 0x44, 0x82, 0xf7, 0xc0, 0xd2, 0x5e, 0xaf, 0x86, 0xed, 0x9e, + 0x23, 0x14, 0x95, 0xb4, 0xb0, 0x84, 0xde, 0x80, 0xd9, 0x20, 0x24, 0xf, + 0xb7, 0xfe, 0x6b, 0xd7, 0x76, 0xc1, 0xc4, 0xf8, 0xb7, 0x6a, 0x28, 0x67, + 0xca, 0xd3, 0x3c, 0x9b, 0x6, 0x5f, 0x32, 0x78, 0xea, 0xcb, 0x61, 0xd, + 0x7d, 0xfa, 0x8e, 0x29, 0x9a, 0x83, 0xb7, 0x89, 0xfe, 0x94, 0x22, 0x44, + 0x21, 0xe, 0x17, 0x17, 0xad, 0x4a, 0xd8, 0xeb, 0x73, 0x40, 0x55, 0xf9, + 0x43, 0x30, 0x60, 0x2f, 0x61, 0xfe, 0xd7, 0x3a, 0xf9, 0xef, 0x46, 0xbf, + 0x91, 0xe5, 0x9a, 0xc8, 0x4f, 0x2, 0x15, 0x6a, 0xe3, 0x5, 0x21, 0x33, + 0xbc, 0xb5, 0x6b, 0x35, 0x23, 0x4f, 0xa9, 0xb1, 0x2a, 0x7f, 0x3d, 0x93, + 0x1b, 0x9e, 0xa3, 0x55, 0xd, 0x95, 0xe6, 0xfc, 0x5d, 0xaf, 0xf, 0x51, + 0x3b, 0x4f, 0xf7, 0x46, 0x95, 0x64, 0xbb, 0xdc, 0xb1, 0xc2, 0x1d, 0x5a, + 0x80, 0xa2, 0xf7, 0x51, 0x3b, 0xa3, 0x2e, 0xb, 0xc5, 0xe0, 0xde, 0x9a, + 0xbd, 0xbe, 0xe2, 0x7f, 0xa, 0xae, 0x24, 0x5c, 0xf9, 0x13, 0x2, 0xb9, + 0xf5, 0x77, 0x49, 0x6e, 0xcb, 0x56, 0x3a, 0x3d, 0xc1, 0xda, 0x3f, 0x5c, + 0xf2, 0xb5, 0x27, 0x5d, 0x55, 0xb1, 0x1a, 0x8a, 0x4a, 0x6e, 0xfe, 0x9e, + 0x22, 0x33, 0x5b, 0x63, 0x4b, 0x4c, 0x69, 0x5f, 0x31, 0xb5, 0xb2, 0x93, + 0x5, 0xd5, 0x2c, 0x9a, 0xe4, 0x1b, 0xcc, 0x85, 0x2e, 0xb8, 0xd8, 0x86, + 0xd7, 0x62, 0x1f, 0x1a, 0x16, 0xa7, 0x91, 0x0, 0xfb, 0xad, 0xa3, 0x21, + 0xc1, 0xe8, 0x4d, 0x4f, 0x19, 0x4d, 0x5c, 0x62, 0x8e, 0x3b, 0xef, 0x32, + 0xd4, 0x1e, 0x2c, 0x4c, 0x5f, 0x99, 0x51, 0x19, 0xff, 0x0, 0xc8, 0x6d, + 0xb1, 0x19, 0x96, 0x74, 0xf8, 0x7, 0x7b, 0xef, 0x7a, 0x12, 0xa1, 0xaa, + 0x52, 0xdd, 0xfc, 0xfe, 0xbb, 0xf2, 0xa2, 0xb0, 0x78, 0x41, 0x44, 0x2f, + 0xa3, 0x16, 0xd6, 0xe6, 0xa2, 0x9a, 0x76, 0x42, 0x6, 0xf1, 0x1d, 0x93, + 0x99, 0xa8, 0xd9, 0x59, 0xb2, 0x4b, 0xa9, 0xe, 0xe2, 0xd3, 0x2f, 0xa, + 0xfe, 0xfe, 0x32, 0xa0, 0xd, 0x42, 0x2a, 0xe7, 0x21, 0xc4, 0xa, 0xa, + 0x76, 0xae, 0x2c, 0xc0, 0x80, 0xfd, 0x19, 0xbd, 0x63, 0xd9, 0x1, 0x50, + 0x42, 0x61, 0x47, 0x12, 0x14, 0xe8, 0x6, 0xb, 0x32, 0x1b, 0x18, 0x56, + 0xc4, 0x5e, 0x55, 0x74, 0x1, 0x41, 0x51, 0x24, 0x3b, 0x4d, 0xde, 0xa0, + 0x3b, 0xda, 0xd4, 0x31, 0xd9, 0x90, 0x87, 0x2a, 0xc, 0xbe, 0xfe, 0x96, + 0x7d, 0x88, 0xc0, 0xc9, 0x6, 0xd8, 0xb9, 0x2a, 0xbb, 0x63, 0xd3, 0x53, + 0x29, 0x7f, 0x7c, 0xd6, 0x18, 0xe6, 0xdd, 0xb7, 0x6, 0x88, 0xd4, 0x83, + 0x2e, 0xf2, 0x7c, 0xf5, 0xa5, 0x55, 0xe1, 0x9f, 0x7f, 0xf1, 0xb8, 0xf4, + 0x9d, 0x67, 0x72, 0xaf, 0xfc, 0x4a, 0x15, 0x6c, 0x75, 0x63, 0xcc, 0x19, + 0xe1, 0x26, 0xa4, 0x29, 0x64, 0x6a, 0xac, 0xd8, 0x5b, 0xe8, 0x38, 0x9b, + 0x55, 0x87, 0xd4, 0xea, 0x25, 0x51, 0x36, 0x4c, 0x57, 0xbf, 0x53, 0xba, + 0x1a, 0x9d, 0xcf, 0x87, 0x4b, 0xb6, 0x24, 0xb5, 0x18, 0x6c, 0x71, 0xab, + 0xea, 0x5, 0x67, 0x7e, 0x36, 0x42, 0xc7, 0x23, 0xb6, 0xf8, 0xe4, 0xe3, + 0x9e, 0x2b, 0x3e, 0x90, 0xd2, 0xc8, 0x5a, 0x6e, 0xd9, 0xd4, 0xf0, 0x4d, + 0x75, 0x68, 0x9c, 0x9a, 0x77, 0x21, 0x45, 0xb0, 0x89, 0x32, 0xc6, 0xfa, + 0x60, 0x46, 0x53, 0x5d, 0xd5, 0xbc, 0x77, 0xcb, 0x8b, 0xbc, 0x27, 0x57, + 0xe, 0x91, 0xf9, 0xc2, 0xdc, 0xa3, 0x2c, 0x3d, 0x1a, 0x6b, 0xbd, 0xc8, + 0x61, 0x96, 0x44, 0x45, 0x47, 0xc4, 0x8e, 0xa, 0xe, 0x7f, 0x4b, 0xb3, + 0xc3, 0x2a, 0x41, 0x9, 0x60, 0x1f, 0x9c, 0x32, 0x7c, 0x9e, 0x66, 0xeb, + 0xa9, 0xf, 0x4d, 0x9f, 0xc4, 0xed, 0x70, 0xd4, 0xfb, 0x88, 0xd8, 0xf5, + 0x3f, 0x78, 0xac, 0xac, 0x15, 0x85, 0x3f, 0x86, 0x59, 0xde, 0xe7, 0x3, + 0xb2, 0xcf, 0x9f, 0x4, 0xd7, 0x69, 0xb, 0x81, 0x6, 0xe5, 0x24, 0x34, + 0x63, 0x8d, 0x42, 0x6e, 0xd1, 0xf6, 0x30, 0xb7, 0xdc, 0x49, 0x6b, 0xeb, + 0xf6, 0x1e, 0x3d, 0xf1, 0xaa, 0xb4, 0x86, 0x8f, 0x75, 0x2e, 0xea, 0xe8, + 0x45, 0x16, 0x8f, 0x47, 0x77, 0x2e, 0x1c, 0xb4, 0x53, 0x8b, 0x2a, 0x3c, + 0x92, 0x2e, 0x19, 0x4, 0xca, 0x6e, 0x21, 0xe3, 0x40, 0x63, 0x31, 0x13, + 0x14, 0x5d, 0x8c, 0x84, 0xe8, 0xeb, 0xbf, 0xf4, 0x85, 0x78, 0x7a, 0x5c, + 0x84, 0xd5, 0x5, 0xf6, 0xdd, 0xa3, 0xfa, 0x3f, 0xee, 0x81, 0x30, 0x99, + 0x6f, 0x5, 0x90, 0x82, 0x3d, 0x6, 0xf1, 0x75, 0x98, 0xe3, 0xe6, 0xa3, + 0x74, 0xfe, 0xc, 0x64, 0xb5, 0xd3, 0xe7, 0xf7, 0xc8, 0x70, 0x42, 0x47, + 0xfe, 0xd2, 0x0, 0xd3, 0xe0, 0x48, 0x2b, 0xd2, 0xcb, 0xbf, 0x62, 0xfc, + 0x48, 0x94, 0x98, 0xfc, 0x19, 0x3c, 0x96, 0x67, 0x3b, 0xf8, 0x63, 0xc6, + 0x5c, 0x7e, 0xdd, 0x88, 0xaf, 0xcf, 0xa5, 0x44, 0xc7, 0xa3, 0x65, 0xa5, + 0xf3, 0x1e, 0x9d, 0xd1, 0x97, 0xd9, 0x3e, 0x75, 0x17, 0xec, 0xbd, 0xd2, + 0x46, 0x42, 0xc, 0xbf, 0x75, 0x26, 0x92, 0x58, 0x7a, 0x6c, 0xd8, 0xd2, + 0xd7, 0x2, 0x9e, 0xeb, 0xf2, 0x71, 0x1c, 0x40, 0x76, 0x3, 0xb, 0xde, + 0xce, 0x1, 0x42, 0x4, 0x4d, 0xda, 0xac, 0xd9, 0x2c, 0x2f, 0xa4, 0x91, + 0xfd, 0xb5, 0xc7, 0xf1, 0xd4, 0x81, 0x5e, 0x7d, 0x94, 0x43, 0xac, 0x7f, + 0x32, 0xf3, 0x2c, 0x58, 0x5d, 0x69, 0x2, 0x44, 0x25, 0x6, 0xe8, 0x61, + 0x7b, 0xfc, 0xe9, 0x80, 0x19, 0xc7, 0xfc, 0x44, 0x33, 0xe9, 0x3b, 0x9c, + 0x94, 0xa9, 0xca, 0xa3, 0x37, 0xaf, 0x72, 0xf3, 0xc0, 0x1f, 0xba, 0xde, + 0xe9, 0x97, 0x3f, 0xe9, 0x8f, 0x78, 0x15, 0x85, 0x99, 0x41, 0x6d, 0x59, + 0x50, 0x6c, 0x0, 0xf, 0x23, 0x2a, 0xb0, 0xb0, 0x1, 0x6c, 0xf6, 0xe6, + 0x8b, 0xe4, 0xe9, 0xcf, 0x37, 0x81, 0x87, 0xf1, 0xf1, 0x95, 0x7e, 0xf8, + 0x3a, 0x1b, 0x8d, 0x8b, 0xf9, 0x85, 0x29, 0xfb, 0xf2, 0xbf, 0xa, 0xfa, + 0x47, 0x44, 0x48, 0x5, 0xa6, 0xdf, 0x97, 0xab, 0xf7, 0x9b, 0x6c, 0xb, + 0xc, 0x8c, 0x5f, 0x4e, 0xe1, 0x9e, 0x12, 0x36, 0xea, 0x39, 0x4b, 0x11, + 0x42, 0xc1, 0x87, 0x82, 0x3b, 0xab, 0x6c, 0x6d, 0x2f, 0xcc, 0x54, 0x5d, + 0x93, 0xff, 0x99, 0x44, 0x9c, 0xb8, 0x56, 0xce, 0x3b, 0x44, 0xf6, 0xfc, + 0xf0, 0xba, 0x77, 0x59, 0xa, 0xdc, 0xd6, 0x61, 0xbd, 0x8b, 0x4a, 0x1e, + 0x77, 0x43, 0xaa, 0xe1, 0xcc, 0x87, 0xc, 0x60, 0xd2, 0xac, 0xf4, 0x86, + 0x2f, 0x12, 0x9e, 0x95, 0x1e, 0x20, 0xba, 0xfd, 0xd0, 0x37, 0xaa, 0xf5, + 0x69, 0x3b, 0xe5, 0x9, 0x31, 0x6d, 0x19, 0x52, 0x38, 0x58, 0x2c, 0xeb, + 0x6b, 0x8f, 0xde, 0x48, 0x7e, 0x54, 0xb8, 0xdc, 0x3e, 0x24, 0xc2, 0x59, + 0x9a, 0xac, 0xa4, 0xdf, 0x1f, 0x5c, 0xbd, 0x6, 0x22, 0xb3, 0x94, 0xca, + 0xc3, 0xbf, 0xa0, 0x8d, 0x56, 0x75, 0x44, 0x28, 0xfe, 0xd8, 0x80, 0x2e, + 0x64, 0x8a, 0x80, 0x5, 0x46, 0xc7, 0x72, 0x3b, 0x8b, 0x8e, 0xfc, 0xbc, + 0x9e, 0x82, 0xbf, 0xd2, 0xea, 0x2a, 0x49, 0xe8, 0x43, 0x5a, 0x18, 0x81, + 0x89, 0x75, 0xa8, 0x89, 0xe7, 0x3e, 0xac, 0x60, 0xcd, 0xea, 0xf3, 0xe3, + 0x15, 0x4b, 0x3f, 0x8c, 0xa9, 0xe4, 0xa, 0xe3, 0x70, 0xa0, 0x60, 0xc7, + 0xf, 0xdd, 0x45, 0x46, 0x1f, 0x69, 0xac, 0xc5, 0xcb, 0xf9, 0xd6, 0xba, + 0x15, 0xa3, 0xad, 0xe0, 0x82, 0xe9, 0x53, 0x2e, 0xaa, 0x72, 0x5, 0xbd, + 0x27, 0xfe, 0x5f, 0x1b, 0x5, 0xfe, 0xd2, 0x61, 0x40, 0xca, 0x82, 0x6b, + 0x15, 0xba, 0xfa, 0x77, 0x9e, 0xfd, 0xa1, 0xb6, 0x5a, 0x17, 0x9f, 0x3f, + 0x54, 0xeb, 0xe0, 0xdb, 0x92, 0x98, 0xc3, 0x35, 0xc1, 0x89, 0x5f, 0x31, + 0x22, 0xde, 0xf0, 0x42, 0xa3, 0xb2, 0x4e, 0xcd, 0x10, 0xb4, 0x8c, 0x50, + 0xab, 0xd7, 0x31, 0xfd, 0x54, 0x49, 0x56, 0x55, 0xe0, 0x72, 0x12, 0x1e, + 0x7, 0xaa, 0x23, 0xfe, 0x5a, 0xb3, 0xed, 0x8a, 0x13, 0xe9, 0x42, 0x98, + 0x66, 0x36, 0xeb, 0xb7, 0x11, 0x92, 0x88, 0xc7, 0xea, 0x38, 0x24, 0x76, + 0x2e, 0x1c, 0x8f, 0x70, 0xa4, 0x9a, 0x68, 0xf4, 0x11, 0xf6, 0xd6, 0x32, + 0x27, 0x2d, 0x9f, 0xc9, 0x60, 0x69, 0xa0, 0x33, 0xf8, 0x50, 0xd4, 0xd6, + 0xe9, 0x8c, 0x8d, 0x27, 0x3f, 0x9a, 0x1d, 0xcf, 0x4f, 0xd3, 0x98, 0x21, + 0xdc, 0x1b, 0x40, 0x92, 0x1f, 0x61, 0x6f, 0x8f, 0x15, 0x38, 0x5d, 0x28, + 0x7d, 0x7, 0xe5, 0xab, 0xa3, 0xa, 0x85, 0x30, 0x95, 0xbe, 0x83, 0x6b, + 0x9d, 0x75, 0x57, 0x57, 0x2f, 0x8a, 0x0, 0xcd, 0x7c, 0xc5, 0xfa, 0xc7, + 0xe, 0x14, 0x9d, 0x35, 0x60, 0x39, 0x72, 0xeb, 0x1f, 0x44, 0x54, 0x3b, + 0xd0, 0x7a, 0x9c, 0x6e, 0x30, 0x97, 0x20, 0xea, 0xe4, 0x69, 0xc5, 0xfe, + 0xd1, 0xa1, 0xe4, 0xfb, 0x98, 0x18, 0x46, 0x20, 0x58, 0x50, 0xb5, 0x92, + 0xe6, 0x74, 0xda, 0x5a, 0xab, 0x2b, 0xd0, 0x76, 0x62, 0xd7, 0x72, 0x81, + 0x2f, 0x72, 0x99, 0xb5, 0xb7, 0x56, 0x0, 0xa7, 0x60, 0x49, 0x1b, 0xd7, + 0xda, 0xb1, 0xc, 0x24, 0xa6, 0xc1, 0x66, 0xad, 0x5c, 0xae, 0xcf, 0xa, + 0xc, 0xc, 0xce, 0xf, 0xd4, 0xf6, 0x88, 0x1f, 0x2e, 0x32, 0x4, 0xae, + 0xc2, 0x30, 0xb1, 0xf8, 0x7b, 0x2e, 0xbc, 0x75, 0xa5, 0x86, 0x11, 0x17, + 0x50, 0xcf, 0xe8, 0xa2, 0x49, 0x2b, 0xa4, 0x8, 0xb9, 0xae, 0x4b, 0x97, + 0xde, 0xda, 0x24, 0x38, 0x3b, 0x29, 0x7a, 0xed, 0x28, 0x58, 0x60, 0x79, + 0x2a, 0x39, 0xf6, 0x67, 0x7a, 0xa3, 0x90, 0x8f, 0xfa, 0xb5, 0x5d, 0x2f, + 0xc8, 0x83, 0xd6, 0x20, 0x1b, 0xca, 0xbc, 0xe8, 0x6a, 0x30, 0x10, 0x8c, + 0x4e, 0x82, 0xf5, 0xa8, 0x18, 0x7a, 0x82, 0x94, 0x43, 0x9a, 0x60, 0x17, + 0xd8, 0xb, 0x25, 0xf3, 0x60, 0xd, 0xbd, 0xd9, 0xfb, 0x22, 0xe, 0xf2, + 0x3a, 0x8f, 0x97, 0xd4, 0x5c, 0x25, 0xb2, 0x64, 0xed, 0x51, 0x8e, 0xe2, + 0x8, 0x1f, 0x54, 0x8a, 0xd5, 0x7b, 0xc8, 0x45, 0x88, 0xce, 0xf4, 0x76, + 0x23, 0x36, 0x76, 0x62, 0x83, 0x23, 0x6c, 0x8a, 0xf6, 0xdf, 0x2e, 0x32, + 0x82, 0x86, 0x2d, 0xc8, 0x5c, 0x73, 0xea, 0xba, 0x86, 0xe1, 0xdb, 0x32, + 0x3b, 0x82, 0x0, 0x26, 0xd9, 0x4f, 0x1, 0x90, 0xcd, 0x4f, 0x6e, 0x31, + 0x4, 0x22, 0xe1, 0x5, 0x0, 0xaf, 0xf7, 0xa7, 0x25, 0x64, 0x6d, 0x32, + 0xc, 0xa8, 0xdc, 0xf, 0x1e, 0x79, 0x9d, 0x1a, 0x31, 0x1d, 0x91, 0xb4, + 0x98, 0x28, 0x94, 0x5a, 0x78, 0x62, 0x82, 0x96, 0x89, 0xd8, 0xe1, 0x77, + 0xb4, 0xfc, 0xef, 0x2f, 0xe1, 0x6a, 0x42, 0xec, 0x60, 0xb5, 0xbb, 0x27, + 0x0, 0x10, 0x4, 0xce, 0xae, 0x41, 0x8a, 0xc6, 0x46, 0xab, 0xaa, 0x45, + 0xcf, 0x4b, 0xb4, 0x93, 0x57, 0x7d, 0x8b, 0x7b, 0xd6, 0xd, 0xbb, 0x51, + 0x54, 0x4e, 0xb4, 0x41, 0xfa, 0x4f, 0x30, 0xfb, 0x41, 0x26, 0x8d, 0xf0, + 0xb2, 0xb7, 0x5a, 0x11, 0x6a, 0x6e, 0xd7, 0xa3, 0xe0, 0x3, 0x8f, 0x12, + 0x29, 0xb2, 0x33, 0x66, 0xd6, 0xe0, 0xa6, 0x35, 0xa4, 0x4, 0x94, 0x78, + 0x19, 0xd9, 0xf3, 0x12, 0xf7, 0x42, 0x4f, 0xf8, 0x63, 0xe7, 0xe, 0xf8, + 0xe0, 0xd7, 0xfc, 0x49, 0x5b, 0x6d, 0xd8, 0xfd, 0xe6, 0xab, 0x0, 0xf0, + 0xef, 0x9, 0x59, 0x87, 0x3f, 0xad, 0x64, 0x8a, 0x30, 0xba, 0xec, 0x47, + 0x49, 0xd9, 0xc9, 0xf8, 0x62, 0x69, 0x8b, 0xa0, 0xc, 0x44, 0x7c, 0xb0, + 0xde, 0x97, 0xd1, 0xba, 0x51, 0xe5, 0xea, 0xd5, 0x49, 0x2f, 0xa0, 0xc7, + 0x78, 0x1e, 0x8, 0xf5, 0x5d, 0x70, 0xaf, 0xdb, 0x6c, 0x30, 0x79, 0x60, + 0x42, 0x78, 0x68, 0xbe, 0x31, 0x9f, 0x90, 0x71, 0x7a, 0x3d, 0xb, 0x95, + 0x7b, 0x93, 0xb2, 0x7a, 0x91, 0xd0, 0x0, 0x51, 0xcd, 0xd8, 0xbe, 0xa7, + 0x43, 0xc4, 0xa3, 0xc0, 0x66, 0x92, 0x6f, 0x85, 0x3d, 0x55, 0xe7, 0x12, + 0x10, 0xef, 0x38, 0xdf, 0x6f, 0x2e, 0xbf, 0xb8, 0x98, 0xf4, 0xce, 0x6c, + 0x6b, 0x5d, 0xca, 0x54, 0x71, 0xc1, 0xba, 0xb1, 0x77, 0x53, 0x38, 0x98, + 0xc8, 0x17, 0x5b, 0xd7, 0xc4, 0x14, 0xa0, 0x56, 0x2, 0x90, 0xd2, 0x43, + 0x51, 0xf0, 0xa8, 0x2c, 0x66, 0x42, 0xf2, 0xbd, 0x63, 0x5c, 0x73, 0xe2, + 0x69, 0xaa, 0x92, 0x85, 0x83, 0x46, 0xc7, 0x93, 0x71, 0xf6, 0xc, 0x1, + 0x52, 0xce, 0x23, 0xc0, 0xeb, 0x77, 0x1a, 0xbb, 0xf, 0x3b, 0x2c, 0x63, + 0x35, 0xff, 0x45, 0x54, 0x3, 0xda, 0x49, 0xd1, 0xd9, 0xed, 0x21, 0x96, + 0xd4, 0x20, 0x39, 0x38, 0x98, 0xea, 0x39, 0xea, 0xc, 0x48, 0x6c, 0x6f, + 0x9, 0x73, 0x37, 0xc3, 0x4d, 0xaf, 0xc5, 0x90, 0xa1, 0x17, 0x92, 0x53, + 0x54, 0x41, 0x9e, 0x4e, 0xf1, 0xc1, 0x2a, 0x49, 0xf5, 0x9d, 0xfe, 0xb2, + 0xdc, 0xc, 0x8c, 0x39, 0xba, 0x9d, 0xf2, 0xd0, 0xf9, 0xdb, 0x7, 0x5e, + 0x7e, 0x94, 0x57, 0x6e, 0xce, 0xa3, 0xee, 0x7d, 0x43, 0x1b, 0x74, 0x46, + 0x70, 0x7, 0xd7, 0xa8, 0x2f, 0x78, 0x4a, 0x48, 0x9c, 0x35, 0xe8, 0x8, + 0xae, 0xd6, 0xdd, 0xdb, 0x2d, 0xd3, 0xfa, 0x1f, 0x68, 0xca, 0x83, 0x5a, + 0x2a, 0x1, 0xee, 0x8b, 0x87, 0x82, 0xf4, 0x46, 0xc1, 0xa2, 0x28, 0x44, + 0xd, 0x7e, 0x8c, 0xe1, 0xd5, 0x16, 0x5a, 0x96, 0x1c, 0xd7, 0xd0, 0x3b, + 0x2d, 0x71, 0xb4, 0x5c, 0xc9, 0x27, 0x9d, 0xcb, 0xc6, 0x7d, 0x5f, 0xae, + 0xbb, 0xfb, 0x77, 0x42, 0x73, 0x17, 0xf5, 0xf0, 0xd2, 0x45, 0xa4, 0xce, + 0xa4, 0xf6, 0x0, 0x54, 0x89, 0x30, 0x34, 0x2b, 0xba, 0x11, 0xa8, 0x9, + 0xfc, 0xae, 0xfb, 0x5b, 0x2a, 0xd9, 0xdc, 0x1c, 0x94, 0x59, 0xb0, 0x79, + 0x74, 0xe2, 0x33, 0xda, 0x96, 0x4d, 0x39, 0xb6, 0xe6, 0x5d, 0x5d, 0x9d, + 0x3b, 0x79, 0x1a, 0x17, 0x2f, 0x65, 0x91, 0x11, 0xf1, 0x34, 0xdc, 0xad, + 0x6e, 0xa1, 0x8, 0xa0, 0x3c, 0xb7, 0xb3, 0xd, 0x69, 0x6c, 0xe8, 0xdd, + 0x39, 0x69, 0xa4, 0x55, 0x1, 0x16, 0xcb, 0xc3, 0x2d, 0x54, 0x61, 0xb6, + 0x98, 0x33, 0xbd, 0x43, 0xc0, 0xee, 0x4b, 0xaf, 0x58, 0x44, 0xf9, 0x6c, + 0x48, 0xd, 0x35, 0x3e, 0xa7, 0x92, 0xb8, 0x83, 0x80, 0xf8, 0x52, 0x26, + 0x8c, 0xa0, 0x4c, 0xb1, 0x9b, 0xc3, 0x37, 0x8b, 0xe1, 0x42, 0x1c, 0x50, + 0x1d, 0x28, 0x4, 0x2d, 0x42, 0xcb, 0x67, 0x97, 0xd4, 0xfa, 0xfa, 0x2a, + 0xaa, 0x8b, 0x3c, 0xbd, 0x70, 0xfa, 0x49, 0x20, 0xcf, 0xc5, 0x96, 0x7e, + 0x5e, 0x30, 0x8c, 0xde, 0x39, 0xc3, 0x39, 0x3f, 0xe, 0xdc, 0xea, 0x30, + 0x52, 0xfa, 0xd7, 0x61, 0x31, 0x12, 0xf0, 0xfd, 0x84, 0x24, 0xad, 0x1a, + 0x1b, 0x8b, 0x24, 0xfa, 0xcc, 0x54, 0xc8, 0xf5, 0xbb, 0x2c, 0xc4, 0xd4, + 0xff, 0x53, 0xe4, 0x8d, 0x42, 0x8b, 0x46, 0xfc, 0x3f, 0xf6, 0xf3, 0xb3, + 0xb, 0xb6, 0x46, 0xed, 0xac, 0xcf, 0xad, 0x97, 0xe8, 0x37, 0x64, 0xde, + 0x2d, 0x2d, 0x30, 0x38, 0xbc, 0xea, 0x23, 0xe8, 0xfe, 0x62, 0x96, 0x3c, + 0xe7, 0x15, 0xc2, 0x7f, 0xab, 0x89, 0x9e, 0xf4, 0x79, 0xab, 0x74, 0x13, + 0x1a, 0xa4, 0x3f, 0x5e, 0xf7, 0x3b, 0xfb, 0xdb, 0x26, 0xee, 0x6b, 0x77, + 0x1d, 0x97, 0x73, 0x95, 0x1f, 0x4c, 0xba, 0xaa, 0xb9, 0x59, 0x73, 0xd7, + 0xba, 0x4a, 0x6f, 0x1a, 0xf6, 0x7e, 0x64, 0x23, 0x8, 0x49, 0xae, 0x2a, + 0x7b, 0x12, 0x2b, 0x65, 0x54, 0xea, 0x8f, 0xcf, 0x23, 0x6c, 0xfa, 0x7, + 0xb5, 0xbb, 0x15, 0x56, 0x26, 0xb, 0xee, 0x38, 0xd1, 0x6e, 0x78, 0x3, + 0x8e, 0xab, 0x93, 0xbf, 0x5d, 0xe4, 0xe4, 0xf0, 0x12, 0x7b, 0x97, 0xee, + 0x66, 0x40, 0x8c, 0xd4, 0x56, 0x1a, 0xdb, 0x1e, 0x39, 0x1e, 0x6c, 0xe5, + 0xbb, 0x3a, 0xe4, 0xf7, 0x60, 0x1b, 0x47, 0x80, 0xa2, 0x14, 0xa0, 0x30, + 0x31, 0xbc, 0x1a, 0xeb, 0x28, 0x1e, 0xd9, 0xf8, 0xe9, 0xc4, 0xfd, 0x67, + 0x3f, 0xf0, 0x7, 0x75, 0xc9, 0x11, 0xb1, 0xd2, 0x72, 0x24, 0xef, 0xab, + 0x6a, 0x37, 0x34, 0x16, 0x42, 0x41, 0x8, 0xd0, 0x50, 0xd2, 0xf7, 0xd6, + 0x1, 0xaa, 0xe7, 0xf4, 0xe9, 0xff, 0x56, 0xa3, 0x62, 0x6b, 0xfa, 0xaa, + 0xb1, 0xc4, 0x9b, 0x4d, 0x8e, 0x33, 0x5a, 0xec, 0xcf, 0x31, 0xba, 0x6f, + 0x91, 0x2e, 0x2d, 0x7b, 0xd3, 0x8d, 0xcc, 0xee, 0x14, 0xb1, 0x17, 0xb2, + 0xad, 0xf1, 0x50, 0x99, 0x40, 0xd9, 0x1b, 0xeb, 0x4b, 0xd1, 0x93, 0x5b, + 0xf8, 0xfd, 0x2c, 0xb0, 0x58, 0xfd, 0x5b, 0x5a, 0x84, 0xbc, 0xe6, 0x4c, + 0xf7, 0xa1, 0x97, 0xb0, 0x43, 0x22, 0x10, 0xf, 0xc6, 0xe, 0x94, 0xba, + 0x6b, 0x4b, 0xf5, 0x46, 0x7f, 0x9c, 0x84, 0x22, 0x1b, 0x2d, 0x5b, 0xfd, + 0xbe, 0xd8, 0x4f, 0xc, 0x8d, 0x5b, 0xad, 0xfe, 0xd1, 0x35, 0x2d, 0x9c, + 0x74, 0xc5, 0xa5, 0x9b, 0x3d, 0xb1, 0xc5, 0x87, 0x38, 0xfb, 0xc2, 0x6d, + 0xe6, 0x11, 0x59, 0x2d, 0x20, 0x88, 0xcd, 0xc2, 0xad, 0xf, 0x75, 0xbd, + 0xd5, 0xec, 0x2f, 0xd0, 0xdc, 0x2a, 0x83, 0x7c, 0x54, 0x5e, 0x31, 0x71, + 0xd4, 0x41, 0xca, 0x2c, 0x52, 0x61, 0x54, 0x60, 0xbf, 0x3a, 0xce, 0x35, + 0x2d, 0x62, 0x0, 0x3d, 0x63, 0x2, 0x35, 0x39, 0x6c, 0x4e, 0xaa, 0xf3, + 0xc4, 0x6e, 0x75, 0x4, 0xcc, 0x12, 0x84, 0x17, 0xd2, 0xb1, 0xee, 0xaf, + 0x4f, 0x9f, 0x2e, 0x3a, 0x7, 0x70, 0xaa, 0x4, 0x3d, 0x8c, 0x37, 0x3, + 0xc4, 0xc7, 0xa1, 0x9d, 0x94, 0x42, 0x43, 0x9c, 0x7e, 0x93, 0x2b, 0x16, + 0xa0, 0xfa, 0x80, 0xdf, 0xc3, 0x70, 0xa4, 0x3a, 0xfb, 0xa8, 0xd6, 0x3e, + 0xf, 0x2, 0x31, 0x97, 0xd4, 0x2, 0x58, 0x17, 0x7e, 0x40, 0x59, 0x46, + 0x70, 0x7c, 0x34, 0x16, 0x63, 0x26, 0x7c, 0xb5, 0xec, 0x50, 0x83, 0x18, + 0x8f, 0x36, 0xe9, 0x5d, 0xaa, 0xeb, 0xd7, 0x15, 0x47, 0xd5, 0xfe, 0xbd, + 0xa4, 0x1c, 0x74, 0xc8, 0x34, 0x8b, 0x70, 0x93, 0xb6, 0x38, 0xdc, 0x4c, + 0xea, 0x6c, 0x8f, 0x20, 0xbd, 0x88, 0x98, 0xe4, 0x76, 0x1e, 0x8, 0xeb, + 0xac, 0x8a, 0x51, 0x56, 0x99, 0x3, 0xc6, 0xa3, 0x43, 0x75, 0x59, 0xd8, + 0x97, 0xf2, 0xe1, 0x99, 0x8a, 0x2b, 0x36, 0xe0, 0x5a, 0x24, 0xf, 0x39, + 0x10, 0x50, 0x6d, 0x9b, 0x85, 0xe8, 0xa8, 0x25, 0x66, 0x38, 0xf9, 0xd9, + 0xc2, 0x97, 0x11, 0xf6, 0x72, 0x3d, 0xbf, 0xd8, 0x6e, 0x9b, 0x1e, 0x5e, + 0x78, 0x45, 0xa9, 0x73, 0xda, 0x2b, 0xd6, 0xbd, 0xd4, 0xd8, 0xfe, 0x3b, + 0x5, 0xa4, 0x6c, 0x4c, 0xf7, 0x92, 0x28, 0x56, 0xa0, 0x4c, 0xee, 0xb3, + 0x27, 0x4a, 0x2a, 0xe8, 0xf5, 0x4f, 0x60, 0x62, 0x66, 0x78, 0x20, 0x21, + 0x77, 0xaa, 0x76, 0x80, 0xa2, 0x31, 0xf0, 0x7b, 0x86, 0x56, 0x86, 0x74, + 0x35, 0xe, 0xf7, 0xab, 0xcc, 0x31, 0x4e, 0xb9, 0xe2, 0xac, 0xe, 0xc9, + 0x9, 0xec, 0xae, 0x4, 0xfd, 0x51, 0xcd, 0xd7, 0xd, 0xd7, 0xf8, 0xb, + 0xc4, 0x3, 0x9b, 0xfe, 0x95, 0xaf, 0x58, 0x48, 0xc2, 0x37, 0xcc, 0xd4, + 0xd2, 0xda, 0xaf, 0x78, 0x44, 0x9c, 0xd4, 0x2a, 0x33, 0x5c, 0xbd, 0xf5, + 0x36, 0xb5, 0xb8, 0xcc, 0xe, 0x4c, 0xb, 0x68, 0x6b, 0xe2, 0x27, 0xdb, + 0x83, 0x7b, 0xa8, 0xb9, 0x34, 0x42, 0x42, 0xb2, 0x7c, 0x7f, 0x22, 0x14, + 0x90, 0xf7, 0xa9, 0x30, 0xda, 0xb8, 0xfe, 0xd7, 0x1d, 0x49, 0x7b, 0x7, + 0x58, 0xd4, 0x82, 0x41, 0xb0, 0xed, 0x47, 0xf, 0x52, 0x4f, 0x5d, 0xa7, + 0x3b, 0x4e, 0xc0, 0xfc, 0x85, 0xe3, 0x97, 0xd6, 0xaa, 0xc4, 0xae, 0x5a, + 0xab, 0x56, 0x8c, 0xac, 0xd, 0xf9, 0xcb, 0x83, 0x3a, 0xf5, 0xdd, 0xb8, + 0x14, 0xbc, 0x37, 0x5c, 0xc1, 0x8a, 0x1b, 0xfe, 0x70, 0xfd, 0x82, 0x49, + 0xf8, 0x53, 0xfd, 0xd6, 0x80, 0x5e, 0x3f, 0x41, 0xe6, 0x59, 0x56, 0x4f, + 0x9d, 0x33, 0x3f, 0x2d, 0x69, 0x15, 0xab, 0x13, 0xe9, 0xc7, 0x2a, 0xe, + 0xd0, 0x5d, 0xa2, 0xb3, 0x2e, 0xa5, 0x47, 0xa4, 0x1b, 0xc9, 0x90, 0xf5, + 0x6c, 0xe3, 0x45, 0x2b, 0x1e, 0x70, 0xfe, 0xb7, 0xe1, 0x3f, 0x4c, 0x94, + 0x87, 0x9f, 0x19, 0x1f, 0xcc, 0xb, 0x72, 0x1b, 0xce, 0xd1, 0x59, 0x6, + 0x98, 0x49, 0x7c, 0xb4, 0x3f, 0x8a, 0xcb, 0xcd, 0x1, 0xc0, 0x9e, 0x23, + 0xda, 0x2b, 0xe5, 0x1e, 0xaa, 0x8b, 0x57, 0xb4, 0x8, 0x42, 0x5f, 0x2a, + 0xfa, 0x1d, 0xb, 0x32, 0x29, 0x13, 0x3b, 0xc6, 0xf7, 0x9c, 0xbf, 0x40, + 0xf2, 0xd7, 0x97, 0x2f, 0x20, 0xa6, 0x4a, 0x0, 0xf6, 0x91, 0xf6, 0x68, + 0x58, 0x86, 0x53, 0xa4, 0x77, 0x3b, 0x19, 0x94, 0x23, 0x82, 0x7, 0x5, + 0x1e, 0x25, 0xd6, 0x70, 0x5b, 0x71, 0x10, 0x46, 0x75, 0x5d, 0x44, 0xd7, + 0x75, 0x30, 0x39, 0x2c, 0x90, 0xe5, 0x61, 0xf4, 0x4a, 0x89, 0xb2, 0x27, + 0xd9, 0x4f, 0x35, 0x45, 0x82, 0xb, 0x9d, 0x47, 0x17, 0x3e, 0x31, 0xed, + 0x9d, 0x53, 0xd4, 0xb1, 0x7d, 0xbe, 0xfa, 0x2b, 0xbb, 0xdb, 0x91, 0x93, + 0xa2, 0xe5, 0x13, 0x44, 0xa1, 0x79, 0xf6, 0xf0, 0x9a, 0x4, 0xab, 0x66, + 0x96, 0x3e, 0xfc, 0x90, 0xd2, 0xe0, 0x8d, 0x91, 0x83, 0xbd, 0x10, 0xf8, + 0x79, 0x9d, 0x5d, 0x5, 0x3e, 0x1, 0x3d, 0x99, 0x28, 0x7a, 0x57, 0x3f, + 0x1a, 0x73, 0x5e, 0x8b, 0x51, 0x55, 0x45, 0xc9, 0x43, 0xb6, 0xc0, 0x3f, + 0xe0, 0x9a, 0x24, 0x59, 0x0, 0xd5, 0x54, 0xea, 0xe5, 0x7c, 0x22, 0x0, + 0xfe, 0x2e, 0x34, 0x2b, 0x24, 0xcc, 0xa3, 0x5, 0xcd, 0x22, 0x19, 0x50, + 0x61, 0xd0, 0x91, 0xb0, 0x99, 0x89, 0xcf, 0x92, 0xf4, 0xf2, 0x68, 0x6b, + 0x15, 0x83, 0xfb, 0x74, 0x5, 0xec, 0x78, 0x36, 0xf8, 0xf8, 0x41, 0x8b, + 0xe9, 0x4e, 0x9b, 0x99, 0xc1, 0x4a, 0x50, 0xdc, 0xe0, 0x76, 0x0, 0xac, + 0x1e, 0x8c, 0xcc, 0x7d, 0x29, 0xaa, 0xea, 0x13, 0x77, 0x79, 0xd1, 0xb2, + 0xc1, 0x1a, 0x34, 0xaf, 0xd8, 0xd5, 0xd, 0x1, 0xe7, 0x9c, 0xd5, 0xfa, + 0xbc, 0xaa, 0xf9, 0xd7, 0xd6, 0xdf, 0x5f, 0x90, 0xee, 0x4a, 0x79, 0x30, + 0xff, 0x52, 0x5f, 0x89, 0x80, 0xbf, 0xa4, 0x40, 0x91, 0xc, 0xe2, 0xe4, + 0x66, 0xc, 0xf6, 0x6a, 0x7f, 0x56, 0x32, 0x8a, 0x25, 0xa5, 0x55, 0xba, + 0x96, 0x9e, 0x1d, 0x96, 0x80, 0xb, 0x6d, 0xb8, 0xee, 0xcf, 0x1c, 0x19, + 0x68, 0x4, 0xda, 0xa6, 0xbe, 0x5e, 0xa, 0x8c, 0x42, 0x7, 0x49, 0x17, + 0x1b, 0x6, 0x61, 0x61, 0x1, 0x45, 0x8d, 0x82, 0x4d, 0x5a, 0x24, 0x12, + 0x2a, 0xaa, 0x8, 0xa9, 0xda, 0xe2, 0xcc, 0x74, 0xf, 0x6c, 0x8c, 0x2e, + 0x84, 0xb0, 0xf8, 0x85, 0x0, 0xab, 0xe4, 0x63, 0x42, 0x34, 0x7f, 0x5c, + 0x6b, 0xca, 0xe6, 0x7, 0xb8, 0x8f, 0xfc, 0x1c, 0x22, 0x73, 0xbb, 0x58, + 0xa8, 0xa5, 0x9c, 0xd6, 0x5, 0x61, 0xda, 0x51, 0x7a, 0x23, 0xf7, 0x49, + 0x6, 0xce, 0x2e, 0x93, 0x88, 0xc5, 0x5e, 0x15, 0x6e, 0x72, 0x53, 0x5e, + 0x35, 0xd8, 0x3c, 0x0, 0x53, 0xa8, 0x71, 0x5e, 0x85, 0x47, 0x24, 0x6e, + 0x74, 0xaf, 0x9d, 0x44, 0xbb, 0xb5, 0x7e, 0xf7, 0x51, 0x97, 0xdd, 0xba, + 0x75, 0xd, 0xbe, 0xe9, 0x72, 0xd0, 0x3f, 0x5a, 0xcb, 0x67, 0x6a, 0xb5, + 0x8f, 0xf9, 0xe9, 0x36, 0x35, 0x4b, 0x19, 0x3e, 0xfd, 0x37, 0x11, 0xf3, + 0xbd, 0x29, 0x81, 0xa6, 0x41, 0x18, 0x22, 0x83, 0xd8, 0x7e, 0x86, 0xf9, + 0xc7, 0x64, 0x2d, 0xfd, 0xa1, 0x8a, 0xa0, 0x16, 0x93, 0x3b, 0x8, 0xe3, + 0xd6, 0x27, 0xbe, 0xaa, 0x9e, 0x5b, 0xed, 0x5d, 0x61, 0x6d, 0x45, 0x2c, + 0x2f, 0x92, 0x77, 0x1d, 0xe, 0xe1, 0x7b, 0x81, 0x5, 0xa4, 0x4, 0x13, + 0x6f, 0x54, 0xe4, 0xa4, 0xaf, 0x3, 0x60, 0xa0, 0x29, 0xcb, 0xbe, 0xd9, + 0xbb, 0xc4, 0x81, 0x6f, 0x31, 0x1, 0x2a, 0xa, 0xef, 0x5b, 0x40, 0xfb, + 0x5f, 0x41, 0xb5, 0x1d, 0x68, 0x94, 0xa7, 0x35, 0xca, 0xf, 0xad, 0x87, + 0xc0, 0x6c, 0x5a, 0x9d, 0xdb, 0x95, 0xe7, 0x16, 0xad, 0x63, 0x29, 0xdc, + 0xd0, 0xe3, 0xf0, 0xc9, 0x71, 0xe0, 0x57, 0xdc, 0xa3, 0xc0, 0x5, 0xf0, + 0x5e, 0xbf, 0xec, 0x34, 0x82, 0xca, 0xf7, 0xb2, 0xb8, 0x73, 0x7d, 0x1, + 0x55, 0xa6, 0xc0, 0x34, 0x69, 0x28, 0xa6, 0x65, 0xdf, 0x44, 0x7b, 0x9b, + 0x65, 0x16, 0x0, 0x28, 0x97, 0x18, 0x2e, 0x48, 0x77, 0xe0, 0x52, 0xb6, + 0xec, 0x3c, 0x57, 0xd3, 0xc6, 0xa7, 0x7, 0xe9, 0x4e, 0x18, 0xd4, 0xed, + 0x28, 0xc1, 0xf1, 0x4a, 0xff, 0xda, 0x2d, 0x27, 0x93, 0x61, 0xb2, 0x5d, + 0xc4, 0x29, 0xf9, 0x4d, 0x1a, 0x52, 0x2c, 0x2c, 0xd9, 0x57, 0x9c, 0x91, + 0xe3, 0x95, 0xe6, 0x85, 0xa4, 0x42, 0xa8, 0xb0, 0xc9, 0x84, 0xa6, 0x4d, + 0x3e, 0x32, 0x7f, 0xf6, 0xa2, 0x8f, 0x14, 0x81, 0xf1, 0x94, 0x11, 0x39, + 0x38, 0xda, 0xa7, 0x27, 0x3a, 0xe6, 0xa8, 0x88, 0x4b, 0xe8, 0x4d, 0x28, + 0xa6, 0x39, 0x0, 0x80, 0x4f, 0x5d, 0x0, 0x56, 0x1c, 0xf0, 0x6e, 0x3e, + 0x82, 0x31, 0x9e, 0x22, 0x89, 0x5d, 0x4c, 0x39, 0x24, 0xa5, 0xf9, 0xf5, + 0xbe, 0xa6, 0xe9, 0xb9, 0xb, 0x2a, 0x17, 0x62, 0x3e, 0x5b, 0xe2, 0x91, + 0x99, 0x35, 0x31, 0x9d, 0xdb, 0x8c, 0x36, 0x36, 0xea, 0x5f, 0xfb, 0x23, + 0x5e, 0xd7, 0xd9, 0x81, 0x48, 0x37, 0xca, 0xc5, 0x87, 0xd0, 0xdf, 0x45, + 0xd2, 0xbe, 0x91, 0x1a, 0x6f, 0x5d, 0x6f, 0xa6, 0xd4, 0x31, 0x79, 0x3e, + 0x6e, 0xa6, 0x4e, 0xcd, 0x14, 0xe, 0x2, 0xd9, 0x28, 0x8b, 0x89, 0x9c, + 0xf8, 0x4d, 0x6c, 0xf0, 0xce, 0x56, 0xf8, 0xa9, 0xa1, 0x83, 0xf1, 0xad, + 0xbe, 0x7c, 0x39, 0xe9, 0x86, 0xd8, 0x1d, 0x82, 0x1e, 0x3b, 0x4c, 0x33, + 0xbe, 0xb3, 0xd0, 0x68, 0x13, 0xc0, 0xd9, 0x5a, 0x6b, 0xb2, 0xaf, 0xea, + 0x54, 0xf8, 0x7c, 0x92, 0x85, 0x3c, 0x1d, 0x9d, 0xca, 0x81, 0x2d, 0xed, + 0xff, 0x19, 0xe7, 0x59, 0x31, 0x66, 0xe, 0x3f, 0xe4, 0xbf, 0x10, 0x0, + 0x93, 0x79, 0x3c, 0x37, 0x20, 0xa6, 0xb7, 0x5c, 0x8d, 0xd3, 0x8a, 0xa2, + 0x36, 0x13, 0xd7, 0xcd, 0xcb, 0x29, 0xb8, 0x90, 0xed, 0x34, 0x9a, 0x26, + 0x44, 0x48, 0x90, 0x5b, 0xb5, 0x6f, 0x49, 0x95, 0xc7, 0xa3, 0xce, 0x82, + 0xb, 0xc3, 0x80, 0xa6, 0xa, 0x4e, 0xd5, 0xfe, 0x90, 0x5e, 0xad, 0x5c, + 0x53, 0xdc, 0xfe, 0x2d, 0x12, 0x6b, 0x25, 0x78, 0x87, 0x3d, 0x8b, 0xda, + 0xe6, 0xda, 0xab, 0x1b, 0x8e, 0xb9, 0x84, 0x4f, 0xf, 0x5, 0xf4, 0x7b, + 0x5f, 0xd, 0x45, 0x5f, 0xd5, 0x2, 0x3f, 0xf0, 0x5a, 0x45, 0xd0, 0x47, + 0xd8, 0x1d, 0x6d, 0xea, 0x77, 0xb, 0x6, 0x7e, 0xd, 0x1c, 0x8f, 0xe, + 0x8a, 0x64, 0xea, 0xb4, 0xa8, 0xbb, 0xdc, 0x54, 0x24, 0xf3, 0x7b, 0xc5, + 0x6b, 0x4d, 0x6f, 0x3e, 0xe8, 0x9, 0xc0, 0x22, 0x89, 0xf1, 0xce, 0xb6, + 0x65, 0x4f, 0x2b, 0xb9, 0xa4, 0xa7, 0x83, 0x92, 0xf9, 0xc1, 0x4d, 0x84, + 0x41, 0xff, 0xf, 0x38, 0x1b, 0xb2, 0x3a, 0x46, 0x88, 0xa3, 0xd, 0x21, + 0xc, 0x6b, 0xbd, 0x73, 0xaa, 0x2f, 0x55, 0xd4, 0x3a, 0x5, 0x67, 0x55, + 0xdc, 0x2d, 0xbf, 0xff, 0x23, 0x4d, 0x11, 0x4e, 0x3a, 0xe8, 0x97, 0xc7, + 0x68, 0x99, 0x2, 0x37, 0x62, 0xab, 0x38, 0x54, 0xe8, 0x61, 0x5e, 0xc2, + 0x81, 0x3, 0x7e, 0x5a, 0x5d, 0xcd, 0xe7, 0x60, 0xfd, 0x11, 0x86, 0x5a, + 0x1e, 0x84, 0xc0, 0xfd, 0xec, 0x94, 0xcf, 0xd6, 0xdd, 0xad, 0x66, 0x71, + 0x7a, 0xf5, 0x6, 0x27, 0xbd, 0x7e, 0x49, 0xfb, 0xfc, 0x39, 0xb6, 0x89, + 0xd5, 0xd8, 0xe1, 0x2, 0xb9, 0x7d, 0x3b, 0xf6, 0x7, 0x11, 0x7e, 0x19, + 0xb2, 0xf, 0xcd, 0x8a, 0xe9, 0x6d, 0x6, 0x56, 0x1b, 0xb5, 0xf1, 0x41, + 0xa5, 0x37, 0xd3, 0xc2, 0xca, 0x47, 0x5, 0x86, 0xa9, 0x25, 0xf7, 0x9, + 0xa7, 0x62, 0xd5, 0x50, 0xa2, 0xe, 0x4f, 0xc6, 0xba, 0x7b, 0x78, 0x50, + 0xde, 0xe9, 0x87, 0x2d, 0x5f, 0xe2, 0x7c, 0xa6, 0xd0, 0x31, 0xa5, 0x13, + 0xc1, 0x9, 0xc0, 0xf6, 0x0, 0x68, 0xa3, 0x31, 0x51, 0xca, 0xfd, 0x83, + 0x6a, 0x8f, 0x62, 0xff, 0xa, 0xa1, 0x96, 0x3e, 0xe6, 0x1d, 0x97, 0x22, + 0x91, 0x11, 0xc0, 0x45, 0xb9, 0xae, 0xd, 0x19, 0x48, 0x7f, 0x54, 0x37, + 0x83, 0x8c, 0x90, 0xc8, 0x9a, 0x1c, 0x74, 0x9e, 0xe6, 0x59, 0xa, 0x3b, + 0x3e, 0xd2, 0x49, 0x9, 0xa1, 0x47, 0xe5, 0xa, 0x5f, 0x79, 0x90, 0x20, + 0xff, 0x42, 0xf3, 0x44, 0x66, 0xd2, 0x43, 0xd5, 0x13, 0xb7, 0xc6, 0x0, + 0xcb, 0x16, 0xca, 0x77, 0x9c, 0x69, 0x6b, 0x2f, 0x95, 0x28, 0xb, 0xfe, + 0x59, 0x60, 0x8d, 0x24, 0x40, 0xc3, 0x41, 0x81, 0xa5, 0x1c, 0x60, 0x64, + 0x40, 0xab, 0x8b, 0x63, 0x6, 0x72, 0xb0, 0x5b, 0x95, 0xa1, 0x87, 0x38, + 0x58, 0x6f, 0xe0, 0x1, 0x90, 0x9a, 0xed, 0xf3, 0xa3, 0x16, 0x87, 0x8d, + 0x70, 0xae, 0x99, 0xa3, 0x52, 0x89, 0x3f, 0xc2, 0xeb, 0xda, 0x18, 0x11, + 0xb3, 0x69, 0x4e, 0xdc, 0xb6, 0x64, 0xd5, 0xbf, 0xdf, 0x92, 0x4f, 0x8c, + 0x1a, 0x78, 0x8a, 0xf5, 0xd9, 0x3b, 0xca, 0x9b, 0x2c, 0xd4, 0x76, 0xc0, + 0x8d, 0x9f, 0xb9, 0x66, 0xa4, 0x52, 0x3f, 0x9d, 0x90, 0xde, 0x4a, 0x85, + 0x10, 0xa5, 0x39, 0x51, 0x18, 0x36, 0x24, 0x87, 0x79, 0x38, 0xc7, 0xae, + 0x7d, 0x32, 0xc, 0xc3, 0x20, 0xf6, 0x2a, 0x31, 0x3b, 0x19, 0x6b, 0x65, + 0x2, 0xff, 0xb0, 0xa3, 0xd4, 0xc7, 0x0, 0xc5, 0xf9, 0x93, 0x67, 0xf0, + 0x62, 0x87, 0x70, 0xd1, 0x91, 0x91, 0x65, 0x6a, 0x57, 0x2e, 0x9e, 0x12, + 0x68, 0x89, 0x1, 0x81, 0x99, 0xf, 0x3d, 0x89, 0x8b, 0x18, 0x50, 0xd4, + 0x74, 0xa1, 0xd9, 0xef, 0x66, 0x71, 0x46, 0xb2, 0x2e, 0xfa, 0x79, 0x9c, + 0x72, 0x2c, 0xdf, 0x6c, 0x12, 0x76, 0x85, 0x6, 0xac, 0x62, 0x4f, 0xd0, + 0x48, 0x3, 0x64, 0x84, 0x2f, 0x7a, 0x21, 0xb3, 0x36, 0xb6, 0x44, 0x33, + 0x4d, 0xf3, 0x30, 0x42, 0x7, 0xa0, 0x98, 0x31, 0xdc, 0x7, 0xa6, 0xe, + 0x77, 0xac, 0xf7, 0xcf, 0x51, 0x82, 0x97, 0x5e, 0x81, 0x56, 0x13, 0x92, + 0x6c, 0xfd, 0x8a, 0x61, 0x9b, 0x62, 0x31, 0x3a, 0x1f, 0x91, 0x54, 0x5a, + 0x76, 0xc7, 0x59, 0x8b, 0x42, 0x86, 0xe3, 0x68, 0xb8, 0xf8, 0xb5, 0xea, + 0x80, 0x63, 0x2f, 0xb1, 0x42, 0x9d, 0x1a, 0x3a, 0xd1, 0xe9, 0x50, 0x20, + 0x9e, 0x62, 0xc6, 0xcc, 0x8, 0x87, 0xa7, 0x1e, 0x58, 0x8e, 0xa8, 0xb6, + 0xd4, 0x2, 0xc, 0x5f, 0x50, 0x3b, 0xc, 0x40, 0x70, 0xf0, 0xfa, 0x8a, + 0x38, 0xdc, 0x89, 0x80, 0x9d, 0xb9, 0xb6, 0xb7, 0x38, 0x4, 0x3a, 0xf5, + 0x37, 0xae, 0x15, 0xde, 0xb1, 0xbb, 0x75, 0x85, 0x3, 0x28, 0x0, 0x1f, + 0xfb, 0xce, 0xb3, 0xf4, 0xa6, 0x57, 0x75, 0xc9, 0x3a, 0xc9, 0xa1, 0x74, + 0x87, 0x19, 0xaf, 0x38, 0x64, 0xc8, 0xd4, 0xf0, 0x51, 0xf3, 0x6a, 0x5e, + 0xdc, 0x18, 0x6b, 0xfd, 0xe6, 0x2a, 0xb1, 0xc0, 0xb5, 0xaf, 0xd5, 0x9f, + 0x3, 0xd8, 0x9e, 0x16, 0xb2, 0xf4, 0x96, 0x71, 0x5d, 0xf6, 0x20, 0xeb, + 0x51, 0x12, 0xb4, 0x5b, 0xa6, 0x18, 0x9f, 0x3e, 0x28, 0x6c, 0x3a, 0x3, + 0xb9, 0x8c, 0x81, 0x7e, 0x93, 0xcf, 0x93, 0x56, 0x89, 0xda, 0x2a, 0x65, + 0x90, 0x49, 0x49, 0x8d, 0x37, 0xa4, 0xac, 0xf2, 0xd2, 0x8e, 0xcf, 0xdc, + 0xfb, 0xd2, 0x17, 0x2c, 0xff, 0xa4, 0x47, 0xa9, 0x6f, 0xb4, 0x81, 0x90, + 0x9f, 0xaa, 0x2b, 0x72, 0x2c, 0x7, 0x82, 0x35, 0xb9, 0x58, 0xaf, 0x6c, + 0xe5, 0x60, 0xc8, 0x14, 0xb7, 0x91, 0x63, 0xc6, 0xf, 0xf2, 0xf6, 0xa, + 0xff, 0xe6, 0x8e, 0x22, 0xf8, 0x4f, 0x54, 0x29, 0xa6, 0x90, 0x9e, 0xd7, + 0x32, 0x3a, 0x1c, 0x68, 0xf6, 0xff, 0xc6, 0x20, 0x2e, 0x3, 0x27, 0x0, + 0xdf, 0x96, 0x56, 0xb9, 0xe9, 0xa9, 0xbf, 0xe3, 0xdc, 0x41, 0xf7, 0xe6, + 0x2f, 0x83, 0x2f, 0xb7, 0x1b, 0x8d, 0x42, 0xfa, 0xba, 0x48, 0x55, 0xb8, + 0x8a, 0x37, 0x1, 0x14, 0xb0, 0x14, 0x46, 0x6, 0x2c, 0x13, 0x2b, 0x95, + 0xe0, 0xd3, 0x49, 0x7e, 0xcc, 0x1d, 0x77, 0x86, 0x93, 0x3d, 0x58, 0x44, + 0x3f, 0x50, 0xb, 0xae, 0x5f, 0x4b, 0x8a, 0x1a, 0xa4, 0x4e, 0xee, 0x76, + 0xff, 0xe9, 0xd5, 0x1f, 0xb8, 0xda, 0x35, 0xb4, 0x75, 0xb7, 0x7c, 0x3a, + 0x9f, 0xc5, 0xd4, 0xe, 0x9, 0xd5, 0x47, 0x11, 0xb7, 0x4c, 0xb4, 0xe1, + 0xb1, 0x51, 0xb7, 0x3b, 0xc0, 0xd4, 0xd6, 0xc3, 0x29, 0x3c, 0xbc, 0x50, + 0xcd, 0x78, 0x24, 0x5, 0xc7, 0x6b, 0x97, 0x3e, 0x80, 0x8b, 0x13, 0x8, + 0x99, 0x7f, 0x7d, 0x5d, 0x64, 0xc, 0xa, 0xbe, 0xb, 0xa5, 0x6, 0xae, + 0x14, 0x79, 0xb0, 0x70, 0x2f, 0xc0, 0xa4, 0x85, 0x37, 0xbb, 0xa7, 0xf8, + 0x51, 0xb, 0x1b, 0x6d, 0xea, 0x1e, 0x44, 0xdf, 0x5b, 0x74, 0xa1, 0x87, + 0x79, 0x5d, 0x6d, 0xac, 0x2e, 0xc7, 0x57, 0xcc, 0xac, 0xc0, 0xa, 0x9c, + 0xdb, 0x4f, 0x2e, 0x67, 0x4e, 0xb5, 0x9d, 0x86, 0x70, 0x82, 0xb3, 0x6b, + 0x4b, 0x5b, 0xfa, 0x17, 0xd1, 0xc9, 0x26, 0x27, 0x64, 0xee, 0x8c, 0xfd, + 0xe2, 0xb, 0xb3, 0x5c, 0x1d, 0x76, 0x98, 0x6e, 0xb, 0x50, 0x7f, 0x21, + 0x1c, 0x7, 0x7d, 0x6a, 0x41, 0xe6, 0xa3, 0x45, 0x56, 0x38, 0x4c, 0x5a, + 0x72, 0x29, 0xa6, 0x2a, 0xb8, 0x90, 0xa6, 0xb6, 0x9, 0x47, 0x8f, 0xef, + 0x59, 0xca, 0xd5, 0x70, 0xe5, 0xf5, 0x4f, 0x49, 0x37, 0x95, 0xa, 0x3f, + 0x76, 0xaa, 0x1c, 0xe0, 0xf0, 0x7b, 0xde, 0xe8, 0x9a, 0x2a, 0xc6, 0x42, + 0xb3, 0x29, 0x5b, 0xa5, 0x30, 0x2a, 0xa6, 0x48, 0xe0, 0x63, 0xe0, 0xbc, + 0xc7, 0xf2, 0xd3, 0x1f, 0x13, 0x6b, 0x76, 0x1c, 0x16, 0x70, 0x48, 0xf2, + 0x57, 0xe8, 0x9b, 0x80, 0x4f, 0x34, 0xf5, 0xaf, 0x52, 0x3f, 0xbe, 0x25, + 0x87, 0xf0, 0x73, 0xcf, 0x7e, 0xab, 0x76, 0x2e, 0xe2, 0x4e, 0x91, 0xc5, + 0x1a, 0xa3, 0x85, 0x2b, 0x95, 0x8, 0xd9, 0x3, 0xca, 0xd0, 0x81, 0xec, + 0xeb, 0x54, 0xe5, 0x90, 0x61, 0x6, 0x99, 0x27, 0x5a, 0x38, 0xae, 0x21, + 0x6a, 0x1b, 0x77, 0x32, 0xca, 0x4c, 0x24, 0xd1, 0xb4, 0xbe, 0x6e, 0x58, + 0x87, 0x73, 0xc3, 0x2b, 0x2a, 0x4f, 0xf6, 0x62, 0x3f, 0x65, 0xc6, 0x39, + 0x4b, 0x33, 0xe1, 0xbd, 0xaa, 0x7c, 0xdd, 0xe9, 0xb1, 0xed, 0xcc, 0x5f, + 0xba, 0x50, 0x79, 0x5, 0x31, 0x3e, 0x84, 0xbe, 0x29, 0x87, 0xeb, 0x76, + 0xa8, 0x65, 0x7a, 0xaa, 0x9c, 0x7, 0xd2, 0x76, 0xb4, 0x1b, 0x8e, 0x1c, + 0xe0, 0x30, 0x49, 0x92, 0x2e, 0x2d, 0xd7, 0xd5, 0x26, 0x82, 0x44, 0x6e, + 0x43, 0x34, 0xcb, 0x41, 0xd7, 0xd9, 0x54, 0x6, 0x44, 0x38, 0xc6, 0x76, + 0x6, 0x1e, 0x67, 0x5d, 0xa9, 0x54, 0xa8, 0x8, 0x30, 0x5b, 0x20, 0x5c, + 0x96, 0x99, 0x10, 0x38, 0xaf, 0x1, 0x6d, 0x66, 0xd, 0x28, 0x77, 0x77, + 0x70, 0x7, 0x1, 0xda, 0x74, 0x3d, 0x4b, 0x30, 0x21, 0xd8, 0x76, 0x92, + 0xfc, 0x67, 0xc7, 0xd5, 0x33, 0xb3, 0x27, 0xcd, 0xe9, 0xd2, 0x2b, 0x1d, + 0x24, 0xc7, 0x66, 0x28, 0xb1, 0x32, 0x15, 0xad, 0xf5, 0x56, 0x92, 0xb0, + 0x25, 0xed, 0x35, 0xa7, 0xe8, 0x71, 0xf3, 0x8f, 0xb8, 0x91, 0xc9, 0xb6, + 0x8, 0x83, 0xbc, 0xb0, 0xbb, 0x2e, 0xb2, 0xa2, 0xdf, 0xb0, 0x2f, 0x2e, + 0x4e, 0xee, 0xd8, 0xbf, 0x18, 0x9d, 0xb2, 0xf8, 0xeb, 0xc0, 0xa4, 0x3, + 0x87, 0x7d, 0x3b, 0x89, 0xb8, 0xf4, 0x1f, 0xde, 0x4b, 0x60, 0x8f, 0x6a, + 0x25, 0x83, 0xb, 0x11, 0x76, 0xda, 0xac, 0x86, 0x4b, 0xa, 0x68, 0x59, + 0x95, 0x2b, 0x21, 0x23, 0x66, 0x56, 0xf4, 0x10, 0xbf, 0xfa, 0x8c, 0xcd, + 0xe6, 0xf, 0x46, 0x65, 0x9a, 0x69, 0x13, 0x86, 0x1a, 0x92, 0xa4, 0x30, + 0x1d, 0xe5, 0xc8, 0xa2, 0xf5, 0x3b, 0x6f, 0x70, 0x88, 0x22, 0x2c, 0x13, + 0x93, 0xf1, 0x26, 0x5b, 0xa, 0x84, 0x80, 0x14, 0xb, 0x92, 0x5f, 0x86, + 0x16, 0x7d, 0xf6, 0x4, 0xab, 0xb8, 0x38, 0x7a, 0x70, 0xa2, 0x79, 0xbd, + 0xfd, 0x19, 0xe3, 0x65, 0x50, 0xaa, 0xde, 0x33, 0xee, 0xa1, 0x25, 0x1, + 0x68, 0x67, 0x93, 0xa3, 0xe0, 0xb7, 0xf8, 0xc7, 0x25, 0x27, 0xd8, 0x16, + 0x11, 0x20, 0x54, 0x54, 0x4e, 0x7e, 0x50, 0x6b, 0xd0, 0x1d, 0xa1, 0x8b, + 0xc, 0x68, 0x3, 0xb4, 0xa6, 0x1c, 0x67, 0x2b, 0x10, 0xb9, 0xfe, 0x27, + 0x3d, 0x87, 0x6e, 0x18, 0x3b, 0xa3, 0x4a, 0x91, 0xe5, 0x8f, 0x58, 0x82, + 0xfc, 0x9c, 0x75, 0xf0, 0x63, 0xcf, 0x45, 0x5f, 0x6e, 0x75, 0x13, 0xaf, + 0xa4, 0xf6, 0xfb, 0xf2, 0xf4, 0x40, 0xc7, 0x40, 0xf0, 0x9f, 0xc3, 0x87, + 0xc9, 0x57, 0xc3, 0xae, 0x7d, 0x12, 0xa7, 0x8d, 0x87, 0x46, 0xd9, 0xc2, + 0x48, 0x1a, 0x6c, 0x3a, 0x5d, 0xb, 0xc, 0x47, 0x49, 0x36, 0x21, 0x5a, + 0x43, 0x5d, 0xaa, 0xd2, 0xa4, 0xf9, 0xf, 0x43, 0x10, 0x3, 0xba, 0xe5, + 0xfd, 0xf, 0x17, 0x8b, 0xa2, 0x43, 0x76, 0xef, 0x28, 0x4, 0xc8, 0x99, + 0x1a, 0x2e, 0xb1, 0xb1, 0x5, 0xb4, 0x6e, 0x49, 0x68, 0x20, 0xc7, 0xd4, + 0xcc, 0xa6, 0xba, 0xd6, 0xe1, 0xba, 0xbf, 0xba, 0x9f, 0x8c, 0x18, 0x11, + 0xf3, 0xde, 0xad, 0xa3, 0x6f, 0x30, 0x6e, 0xdd, 0x28, 0x64, 0x71, 0x87, + 0xc5, 0xf, 0xc1, 0xe7, 0x46, 0x49, 0x65, 0xee, 0x33, 0x8b, 0x29, 0x4a, + 0xbb, 0xc2, 0xa4, 0x4e, 0xb, 0x54, 0x7a, 0x34, 0xcd, 0xe0, 0xe4, 0xce, + 0x30, 0x68, 0x43, 0xa8, 0x92, 0xb7, 0x33, 0x87, 0xc3, 0x1e, 0x99, 0x2e, + 0x72, 0xd4, 0x1, 0x90, 0x56, 0x4f, 0xff, 0x39, 0x4f, 0x16, 0x81, 0x5f, + 0xef, 0x97, 0xfa, 0xb2, 0x63, 0x48, 0x3b, 0x8e, 0x32, 0xcd, 0x10, 0x58, + 0xae, 0x14, 0x79, 0x86, 0xc7, 0xea, 0x3f, 0x9a, 0x86, 0xd4, 0x2f, 0x72, + 0xb1, 0x48, 0x23, 0x5c, 0xb0, 0x98, 0x31, 0xea, 0x4d, 0xe6, 0x75, 0x29, + 0xa0, 0x37, 0x25, 0xbe, 0x79, 0xde, 0xc5, 0x5b, 0x42, 0x87, 0xc1, 0xd8, + 0x8b, 0xf2, 0xe0, 0x30, 0x5a, 0xb4, 0xf3, 0x84, 0xc8, 0x6c, 0xc8, 0xd5, + 0x8d, 0x2e, 0x6f, 0x15, 0x91, 0xd5, 0xbd, 0x9, 0x1a, 0x69, 0xd2, 0xd1, + 0x98, 0x4f, 0x5f, 0x72, 0x63, 0xc3, 0xc6, 0xcf, 0x9d, 0x64, 0xee, 0xda, + 0x29, 0x7, 0xf4, 0x34, 0xba, 0xb9, 0xac, 0xdd, 0x57, 0x55, 0x71, 0xa6, + 0x9e, 0x4d, 0x83, 0x1b, 0xfb, 0x79, 0xe0, 0x2e, 0x8a, 0xe5, 0xa5, 0x63, + 0xfc, 0xdc, 0xa8, 0x34, 0xd5, 0x5a, 0x9d, 0x14, 0xdf, 0xc1, 0x13, 0x75, + 0xe5, 0x7c, 0xf8, 0x8d, 0x96, 0x3a, 0x8e, 0xc3, 0x22, 0xb2, 0xfa, 0xe2, + 0x9b, 0x83, 0x8d, 0xe7, 0x30, 0xbd, 0xa9, 0xf4, 0x9c, 0x5a, 0xb6, 0xda, + 0x80, 0xcd, 0x9d, 0x78, 0x40, 0xb4, 0xda, 0xf2, 0xda, 0xcb, 0xcb, 0x20, + 0x99, 0x4a, 0x4, 0xc0, 0x7e, 0xc4, 0x8e, 0x32, 0xb6, 0x37, 0xfa, 0x9d, + 0x9a, 0xb3, 0x17, 0xf4, 0x8f, 0x71, 0x80, 0x39, 0x5f, 0x48, 0x76, 0x6, + 0x50, 0x5a, 0x5f, 0xf6, 0xc8, 0x28, 0x69, 0x4b, 0xdf, 0x1, 0xd2, 0xe8, + 0xc0, 0xef, 0x8a, 0x79, 0xcf, 0x9d, 0xd0, 0x62, 0xbb, 0x96, 0xfa, 0x8f, + 0xb, 0x7f, 0x8, 0xd7, 0xfb, 0x7e, 0xbc, 0x90, 0x54, 0xf8, 0xb8, 0xd6, + 0x92, 0x5f, 0xf5, 0xf8, 0x6d, 0x2f, 0x14, 0x51, 0x32, 0xbd, 0x4, 0x94, + 0xc2, 0xa, 0x9, 0xd0, 0xb, 0x9a, 0x9b, 0x7a, 0xae, 0x90, 0xb9, 0xb2, + 0x42, 0xdf, 0xa0, 0x29, 0x13, 0xc8, 0xf5, 0x53, 0x85, 0x6a, 0x30, 0xa8, + 0x9, 0xf6, 0x7e, 0x83, 0x6b, 0x9c, 0x55, 0x8d, 0xdb, 0xad, 0xfd, 0xba, + 0x41, 0xda, 0x6c, 0x7f, 0x19, 0xb4, 0x81, 0xb8, 0xfd, 0x9d, 0x76, 0xa7, + 0xa, 0x5, 0x3a, 0x9b, 0x56, 0xf0, 0x8, 0x4a, 0xd6, 0x92, 0xb0, 0x53, + 0xe3, 0x1e, 0x3, 0x92, 0xa9, 0xb4, 0x59, 0xf5, 0x50, 0x7f, 0x4f, 0xe8, + 0xde, 0x85, 0xae, 0x10, 0x73, 0xee, 0x1c, 0x2e, 0x4e, 0x90, 0xcd, 0x6f, + 0x6, 0x69, 0x52, 0x56, 0x7e, 0xbb, 0xeb, 0xee, 0xb8, 0xf5, 0x10, 0x3e, + 0xd0, 0x77, 0x1e, 0x70, 0xdb, 0x15, 0x2e, 0x3c, 0x56, 0x46, 0xfd, 0xa3, + 0x9c, 0x4e, 0x90, 0x1e, 0x5, 0x41, 0xa1, 0x62, 0x7c, 0x5, 0xbe, 0xc0, + 0xa, 0x87, 0x1d, 0x3b, 0x1, 0x94, 0x9c, 0x7f, 0xbd, 0x58, 0x98, 0x94, + 0x52, 0xdd, 0xf8, 0x8a, 0x23, 0xc8, 0xc5, 0x2e, 0x98, 0xf3, 0xf3, 0x1d, + 0x5e, 0x27, 0x2f, 0x44, 0x25, 0x57, 0x1c, 0xde, 0x86, 0xd7, 0xbc, 0x86, + 0x20, 0x65, 0x4c, 0xaa, 0x79, 0x52, 0x61, 0x83, 0x48, 0xdf, 0x58, 0x99, + 0xff, 0x9b, 0x4, 0xf3, 0xd9, 0xbd, 0x19, 0x2, 0x7a, 0xa5, 0x4d, 0xf0, + 0x4b, 0x88, 0x1c, 0xae, 0xe3, 0x5b, 0x9e, 0xac, 0x6c, 0xc1, 0x71, 0x33, + 0x2a, 0xf7, 0x38, 0x5a, 0x70, 0xdf, 0xef, 0x0, 0x1c, 0x32, 0x83, 0x8, + 0x18, 0xe9, 0x72, 0xfc, 0x2c, 0x38, 0xec, 0x5b, 0x4e, 0xab, 0xfc, 0xc0, + 0xab, 0xd5, 0x6, 0xa7, 0x5e, 0x11, 0x2f, 0xaf, 0xeb, 0xa5, 0x7a, 0x5a, + 0x90, 0xd6, 0x0, 0x84, 0x40, 0x4c, 0x80, 0xe, 0xd3, 0xe4, 0x85, 0x27, + 0x3e, 0x79, 0x67, 0xe1, 0xc7, 0x80, 0x60, 0x16, 0x86, 0xc3, 0x73, 0x6c, + 0x97, 0x94, 0x88, 0xd4, 0x10, 0x72, 0x7b, 0x84, 0xb5, 0x41, 0xa6, 0x12, + 0x8f, 0xc7, 0xcd, 0x1a, 0x8, 0x5, 0xd1, 0x1c, 0xa4, 0x94, 0x41, 0xe, + 0x0, 0x47, 0x94, 0x45, 0xb1, 0x3b, 0x9, 0x51, 0x82, 0x5e, 0x22, 0x5f, + 0xab, 0xf7, 0xeb, 0xa3, 0x5e, 0x22, 0x7, 0xe9, 0xd6, 0x8e, 0xa5, 0x50, + 0x92, 0x5, 0x8c, 0xac, 0x91, 0xd8, 0xba, 0xac, 0x3c, 0xd4, 0x9, 0x12, + 0x6c, 0xe5, 0xc5, 0x6b, 0xe0, 0x53, 0xd2, 0x1f, 0x8c, 0xc4, 0xd8, 0xc2, + 0xcf, 0x84, 0x33, 0xa3, 0xaf, 0xf1, 0xbb, 0x67, 0xbb, 0x2f, 0xa1, 0x50, + 0xce, 0x2a, 0xf3, 0xf1, 0xe9, 0x43, 0x4d, 0xb3, 0x35, 0x21, 0x8, 0x5c, + 0x30, 0x62, 0x2b, 0xa3, 0x42, 0xca, 0x5b, 0x1c, 0xd7, 0x85, 0xff, 0xac, + 0x9a, 0x77, 0x6f, 0xcc, 0xac, 0xea, 0xe7, 0xb7, 0x5c, 0xd8, 0x76, 0x5b, + 0xde, 0x37, 0x1, 0x1c, 0x7e, 0x70, 0x4d, 0x88, 0x54, 0xaa, 0xc9, 0x34, + 0x42, 0xc7, 0xc5, 0x34, 0x11, 0x61, 0x39, 0x3c, 0xb6, 0x5b, 0x41, 0x22, + 0xa3, 0x74, 0xec, 0xa7, 0x6e, 0x3c, 0xb2, 0x20, 0xf7, 0xbb, 0x4e, 0x6b, + 0xbc, 0x68, 0x9a, 0x2a, 0x7d, 0x86, 0xdd, 0xc4, 0xa0, 0x57, 0x86, 0x45, + 0x70, 0x3f, 0xfa, 0xae, 0xd6, 0xab, 0x1b, 0x1c, 0x93, 0x7a, 0x5e, 0x32, + 0xdc, 0x9e, 0xc8, 0x61, 0x8f, 0x51, 0x5, 0xe1, 0x16, 0x54, 0x58, 0x9, + 0x1, 0xd, 0x8e, 0x37, 0x5c, 0xaa, 0xbc, 0xb2, 0xe4, 0xbc, 0x44, 0xa2, + 0xf8, 0x47, 0x7c, 0xc5, 0x48, 0x5c, 0x2f, 0x24, 0xba, 0x8d, 0x5c, 0x14, + 0xcc, 0x78, 0x6c, 0x3e, 0xce, 0xfd, 0xfd, 0x7e, 0x94, 0xcf, 0x48, 0x62, + 0x66, 0x45, 0x8b, 0xf3, 0x79, 0xa0, 0x34, 0xb7, 0x37, 0x66, 0x84, 0xe1, + 0x51, 0x3e, 0xe8, 0x18, 0x4b, 0xb, 0xfd, 0xea, 0xb2, 0x1d, 0x8a, 0xe4, + 0xa, 0x31, 0x91, 0x4e, 0x86, 0x59, 0xf6, 0xa8, 0x96, 0x88, 0xe8, 0x9c, + 0xa, 0x38, 0x7, 0x3, 0x17, 0xcb, 0xb6, 0x5b, 0x16, 0xf1, 0xce, 0xf1, + 0x12, 0xd4, 0x7e, 0x43, 0xb7, 0x79, 0x1d, 0x40, 0x4c, 0x67, 0xbb, 0xca, + 0xac, 0xae, 0x18, 0xb2, 0x6c, 0x5e, 0xf4, 0x58, 0x48, 0xe2, 0xb9, 0x51, + 0x8c, 0x2b, 0x0, 0x62, 0x7f, 0x9e, 0x7a, 0x3f, 0x5b, 0xf1, 0x92, 0x80, + 0xd8, 0x15, 0x35, 0x89, 0x20, 0xa5, 0x1d, 0x7e, 0xbe, 0xe7, 0x5a, 0xe1, + 0x4e, 0xd0, 0x6, 0xc8, 0xce, 0x57, 0x59, 0x6b, 0x2d, 0x55, 0x43, 0x3b, + 0x6b, 0x4f, 0x7a, 0x84, 0x18, 0xca, 0x96, 0xeb, 0x0, 0x45, 0x0, 0x69, + 0xd8, 0x58, 0xe7, 0x27, 0xc3, 0xcd, 0x65, 0x30, 0x97, 0x7e, 0xf1, 0xe, + 0x93, 0xd, 0x26, 0x67, 0xa5, 0xd6, 0xbc, 0x86, 0x88, 0x2e, 0x85, 0x4b, + 0xc5, 0x8e, 0x8c, 0xf7, 0xe8, 0x6f, 0x62, 0x2b, 0x7f, 0x27, 0x63, 0x1d, + 0xcf, 0x89, 0x48, 0x87, 0xb8, 0x8f, 0x50, 0x61, 0x54, 0x92, 0xf8, 0xfb, + 0xd, 0x73, 0xbd, 0xf8, 0xd3, 0xfd, 0x6a, 0xa4, 0x4e, 0x93, 0xae, 0x3f, + 0x70, 0x7c, 0xdb, 0x6d, 0x41, 0xc0, 0x87, 0x67, 0xcd, 0xdf, 0x2c, 0x41, + 0xa3, 0x45, 0x37, 0x9a, 0x81, 0x5, 0xd0, 0x77, 0x61, 0xf5, 0x6e, 0x61, + 0x4c, 0x53, 0x5, 0xf0, 0xbb, 0x7c, 0x5d, 0xbc, 0x2f, 0x20, 0x46, 0xb6, + 0x55, 0x41, 0x71, 0x13, 0x8d, 0x91, 0x9e, 0x95, 0xc6, 0xf3, 0xbe, 0x56, + 0x43, 0x69, 0xc6, 0x4b, 0xb7, 0x20, 0xb1, 0xd5, 0x2b, 0x8b, 0x8c, 0xc2, + 0xda, 0x39, 0x64, 0xa0, 0x5e, 0x6c, 0x63, 0x70, 0x8c, 0x5a, 0xb4, 0x8c, + 0x4b, 0xb7, 0xf8, 0x6d, 0xf1, 0x9b, 0xe1, 0x65, 0x82, 0x5f, 0xe2, 0x79, + 0x1e, 0x96, 0x5f, 0xa1, 0x36, 0x6f, 0x3f, 0xce, 0x83, 0xcf, 0xbb, 0x69, + 0xdf, 0xbc, 0xb5, 0x65, 0xf9, 0xfa, 0x55, 0x1, 0xc8, 0xc8, 0xf9, 0xd, + 0x6e, 0xc, 0x46, 0xbc, 0xe0, 0x3a, 0xae, 0x29, 0xd, 0x86, 0xcc, 0xde, + 0xbe, 0x67, 0x2d, 0x8b, 0xf, 0x96, 0xe1, 0xc2, 0x8c, 0x9b, 0x98, 0x6c, + 0xb, 0x5f, 0x56, 0x4, 0xf4, 0xa5, 0x8, 0x73, 0xdc, 0xcf, 0xf7, 0xdc, + 0xcc, 0xc9, 0x53, 0xf0, 0x85, 0x56, 0x99, 0x3c, 0x8a, 0xe5, 0xf, 0x14, + 0x48, 0x3e, 0xba, 0x59, 0x41, 0x99, 0xe4, 0x0, 0xe1, 0xc9, 0x33, 0x5f, + 0xcf, 0x4, 0x31, 0x66, 0x31, 0xd6, 0xa9, 0xe1, 0x1d, 0x39, 0xa, 0x17, + 0x6, 0xd6, 0xb4, 0x12, 0xe0, 0xf, 0x77, 0xcb, 0xf2, 0x1d, 0x3f, 0xfc, + 0x6a, 0x81, 0xae, 0x32, 0x12, 0x3e, 0x6c, 0x6f, 0x7c, 0xff, 0x61, 0xe0, + 0xe2, 0x4d, 0x71, 0x76, 0x25, 0xc3, 0x46, 0x37, 0x89, 0xaf, 0xef, 0xbd, + 0x71, 0x27, 0xf8, 0x22, 0x6d, 0xb7, 0xac, 0xad, 0xb4, 0xab, 0xfe, 0x4b, + 0xc2, 0x55, 0x8, 0x5, 0x6c, 0x58, 0x3a, 0xf3, 0x76, 0x57, 0x49, 0x69, + 0x26, 0xb9, 0xcc, 0x8c, 0xba, 0x1a, 0xb7, 0xf, 0x6e, 0x81, 0xda, 0xff, + 0xba, 0xf9, 0xed, 0x65, 0x97, 0x9b, 0x23, 0x3a, 0xb6, 0xd4, 0xe4, 0x7, + 0x9e, 0xbf, 0x87, 0xe2, 0x1d, 0x75, 0x96, 0x98, 0x8c, 0xfa, 0xc0, 0x78, + 0x26, 0x90, 0x93, 0xd8, 0xaa, 0x25, 0xc2, 0xdf, 0x52, 0xa0, 0xdb, 0xc6, + 0x1c, 0xc8, 0xf3, 0x2d, 0xa, 0xca, 0xf4, 0xa3, 0x35, 0xf6, 0xb4, 0x60, + 0xe8, 0x5, 0x8f, 0x95, 0x48, 0x81, 0x8f, 0xc7, 0x51, 0x41, 0x87, 0x38, + 0xd7, 0x44, 0x85, 0x5a, 0xc8, 0x14, 0xbe, 0x34, 0xbc, 0x28, 0xde, 0xc4, + 0x2b, 0x7c, 0x46, 0x46, 0x59, 0xa2, 0xfe, 0x8a, 0x21, 0x3, 0xe6, 0x46, + 0x46, 0x18, 0x7f, 0xfc, 0x92, 0xa8, 0xef, 0xc, 0x13, 0x3e, 0xb4, 0x3b, + 0x3d, 0x2b, 0x88, 0x66, 0x83, 0xdf, 0xc4, 0xff, 0x6d, 0x95, 0x8d, 0xf4, + 0x96, 0xf3, 0x80, 0x4, 0xb8, 0x9d, 0x3a, 0x1, 0xba, 0x6, 0x37, 0x2f, + 0xc7, 0x40, 0x41, 0x20, 0x48, 0x15, 0xe2, 0x19, 0xcb, 0xda, 0xea, 0xee, + 0x70, 0xcf, 0x16, 0xa3, 0x85, 0x70, 0xa3, 0x31, 0x2d, 0xa7, 0xff, 0xe1, + 0xa5, 0xbd, 0xa6, 0x84, 0x13, 0xb2, 0x62, 0x38, 0x8, 0xcd, 0x7c, 0xd1, + 0xca, 0x36, 0x35, 0x70, 0xbd, 0x93, 0x36, 0x39, 0xb9, 0x48, 0x9c, 0x9b, + 0xb6, 0x77, 0xe1, 0xb9, 0xcc, 0x14, 0x6a, 0xfd, 0x4a, 0xc7, 0xec, 0xaf, + 0x11, 0x61, 0xdd, 0x9b, 0xe, 0x1f, 0x33, 0xf4, 0x3f, 0x93, 0x77, 0x29, + 0x98, 0x61, 0x11, 0x9a, 0xdd, 0x45, 0xe, 0xca, 0x67, 0xf3, 0xa5, 0xe7, + 0x29, 0x27, 0xb, 0xc4, 0x92, 0x5d, 0x8a, 0x1a, 0x29, 0x5d, 0xcb, 0x47, + 0xdf, 0x38, 0x1f, 0x71, 0xae, 0x8c, 0xfa, 0x14, 0x65, 0xee, 0xf4, 0x5c, + 0x1c, 0xb1, 0xa1, 0xb0, 0x91, 0x3a, 0x6f, 0xf1, 0x5f, 0x7d, 0x83, 0xc5, + 0x73, 0x6, 0x90, 0x6, 0xe9, 0x57, 0xeb, 0x6b, 0x31, 0x63, 0xbb, 0xa4, + 0xa7, 0xf4, 0x57, 0x88, 0x9b, 0x23, 0x96, 0xe3, 0x1c, 0xce, 0x8d, 0x8, + 0x71, 0x90, 0xb5, 0x48, 0x63, 0x0, 0x0, 0x74, 0x99, 0xa, 0x13, 0xb8, + 0xa5, 0x35, 0x5d, 0xff, 0x26, 0x97, 0x22, 0xe4, 0x34, 0x39, 0xd2, 0xbe, + 0xa6, 0xca, 0x1e, 0xca, 0xdf, 0x16, 0x6d, 0x5a, 0xd3, 0xa8, 0xef, 0x68, + 0x61, 0xf6, 0x31, 0x86, 0x2c, 0x12, 0x96, 0xe0, 0xc8, 0xa, 0x45, 0x3a, + 0xec, 0x81, 0x8c, 0x45, 0xf3, 0x8e, 0x77, 0xbc, 0xc2, 0xf2, 0x66, 0x2e, + 0x34, 0xf9, 0xbc, 0x21, 0xb0, 0xbc, 0x1f, 0x16, 0xc7, 0xd2, 0x78, 0x90, + 0xa6, 0xec, 0x6, 0x6d, 0xf1, 0x30, 0x71, 0x2f, 0x60, 0x1c, 0xf5, 0x91, + 0xe, 0xf6, 0xa1, 0x17, 0x20, 0xb3, 0x81, 0x2d, 0xe7, 0xef, 0xec, 0x8b, + 0xa0, 0x93, 0x67, 0x41, 0x29, 0x51, 0xfc, 0x6b, 0xaa, 0x6b, 0xf, 0xf0, + 0xeb, 0xe9, 0x6, 0xb0, 0x3, 0xae, 0xf0, 0x9b, 0xd2, 0xa8, 0x92, 0x14, + 0x7a, 0x6c, 0xff, 0x24, 0x3f, 0x2b, 0xfb, 0x1, 0xdd, 0xf1, 0x36, 0x3e, + 0x7b, 0xc8, 0x53, 0x56, 0x34, 0xc0, 0x9, 0xb1, 0x6c, 0xd9, 0xe9, 0x34, + 0x16, 0xc0, 0xa, 0x1f, 0xbc, 0x7d, 0x16, 0x51, 0x8a, 0xa5, 0x62, 0xf0, + 0xf3, 0x33, 0x46, 0x90, 0x45, 0x63, 0x3b, 0x4f, 0xe6, 0xfe, 0x6d, 0xe4, + 0xe5, 0x88, 0x8c, 0xe1, 0x6f, 0xdb, 0x9f, 0xbb, 0x79, 0xd8, 0x92, 0x71, + 0x9c, 0xe9, 0x8b, 0xca, 0x8, 0x6a, 0x25, 0x3f, 0x4f, 0x77, 0x85, 0xf0, + 0x29, 0xac, 0x8, 0x3f, 0x5f, 0x6f, 0xda, 0x95, 0x9c, 0x1b, 0xc2, 0x81, + 0x8b, 0xdb, 0xd3, 0x60, 0xcb, 0xf6, 0xd9, 0x6b, 0x42, 0x80, 0x3b, 0x42, + 0x6f, 0x96, 0xf4, 0xc8, 0xd6, 0x7e, 0xbf, 0x79, 0x8f, 0x26, 0x92, 0x7f, + 0x1a, 0x99, 0x8e, 0xbb, 0x3d, 0xd6, 0xd0, 0xb0, 0x82, 0x88, 0x8, 0xde, + 0x22, 0x7a, 0x97, 0x3b, 0x7c, 0xba, 0xc8, 0xc5, 0x54, 0x37, 0x50, 0xc1, + 0x3f, 0xf7, 0xaa, 0x8d, 0xe5, 0x7f, 0x3, 0x4a, 0xdf, 0x63, 0x3b, 0x82, + 0xb, 0x59, 0xb6, 0x4f, 0x56, 0x7c, 0x1e, 0xb4, 0xc, 0xe4, 0xbe, 0x54, + 0x11, 0xa0, 0x6c, 0xfa, 0xce, 0x3a, 0x15, 0x2e, 0xf0, 0x7f, 0x98, 0xd3, + 0xe7, 0xcf, 0x48, 0xa7, 0x9e, 0xb9, 0xf8, 0x25, 0xfa, 0xfb, 0xdf, 0xb5, + 0xe3, 0x61, 0x6e, 0x1e, 0xd7, 0xb0, 0x3b, 0x16, 0x98, 0xee, 0x53, 0x0, + 0x68, 0x98, 0x66, 0x16, 0x64, 0x78, 0x44, 0x23, 0x20, 0x4d, 0x50, 0x65, + 0xf7, 0xf1, 0x25, 0x9f, 0x58, 0x3c, 0xdd, 0x6e, 0xb9, 0xa, 0xb7, 0x6, + 0xa7, 0x7b, 0xd2, 0xa3, 0xea, 0x9f, 0xcb, 0xb, 0xe7, 0x79, 0xd4, 0xde, + 0x50, 0x3a, 0x4d, 0x52, 0xaa, 0x0, 0x86, 0x86, 0x1b, 0x4, 0x91, 0x82, + 0xc4, 0x9d, 0xd4, 0x76, 0x4c, 0xe9, 0xb3, 0xcb, 0x42, 0xf9, 0x5b, 0xeb, + 0x0, 0xb2, 0x77, 0xf8, 0x18, 0x14, 0x22, 0x73, 0x51, 0xc, 0xc, 0x23, + 0x16, 0xe1, 0xf4, 0x24, 0x5b, 0x4b, 0x2a, 0xec, 0xf1, 0x9, 0x1b, 0xb1, + 0x18, 0x2b, 0xdf, 0xb, 0x1, 0xf6, 0x58, 0x1, 0xc2, 0xd0, 0xba, 0x59, + 0x21, 0xa8, 0xc6, 0x1a, 0x54, 0xf0, 0x91, 0xf5, 0x88, 0x61, 0x8e, 0xec, + 0x72, 0xac, 0x1e, 0xd, 0x8b, 0x91, 0xc5, 0x4c, 0x64, 0x13, 0x5e, 0x15, + 0xed, 0x25, 0x1c, 0x5b, 0x25, 0xc9, 0x53, 0xbb, 0x95, 0x55, 0xd0, 0x3d, + 0x98, 0xaa, 0xee, 0x6f, 0xe6, 0xd0, 0xc2, 0x6e, 0x3e, 0x91, 0xbd, 0xb1, + 0xd2, 0x5c, 0x32, 0x14, 0x18, 0x46, 0xb9, 0xad, 0xe0, 0x71, 0x3c, 0x6c, + 0x41, 0x52, 0x1c, 0xda, 0x31, 0x2e, 0xc9, 0x9e, 0xde, 0xc5, 0x8b, 0xb4, + 0xaa, 0x37, 0x18, 0xf4, 0xb4, 0x55, 0x18, 0x44, 0x70, 0x1a, 0xa1, 0x61, + 0x8f, 0x67, 0xc2, 0xef, 0x6a, 0x4e, 0x78, 0x57, 0xf7, 0x7c, 0x91, 0x9c, + 0xf3, 0xbb, 0x4b, 0x46, 0xb5, 0xc1, 0x5b, 0xc, 0x72, 0xf0, 0xa6, 0xd0, + 0x9d, 0xf2, 0xc, 0x63, 0xea, 0xe6, 0xa3, 0x7c, 0x8f, 0xde, 0xc5, 0xa1, + 0xe8, 0x8e, 0x33, 0x58, 0xf6, 0xe6, 0xb4, 0x50, 0x39, 0x9, 0x66, 0xd, + 0xf7, 0x38, 0xa9, 0x90, 0x51, 0xf3, 0x97, 0xce, 0x16, 0xe8, 0x32, 0x8b, + 0x13, 0x74, 0x54, 0xec, 0x22, 0x44, 0x2f, 0x2f, 0xf0, 0x95, 0x31, 0xab, + 0xf5, 0xe6, 0x34, 0xe4, 0x71, 0xd0, 0xa8, 0x5d, 0xda, 0x8f, 0x4b, 0x5c, + 0x3c, 0x71, 0x66, 0xc2, 0x56, 0xa1, 0x46, 0x1d, 0x61, 0x5e, 0x2, 0x17, + 0x63, 0x96, 0xb5, 0xb, 0x25, 0xe1, 0xb2, 0xb9, 0x3f, 0xe4, 0xc1, 0xd, + 0x52, 0xfc, 0x7a, 0x13, 0x69, 0x19, 0xec, 0xa1, 0x7a, 0xa4, 0xe8, 0x36, + 0x8b, 0xe1, 0x60, 0xd5, 0x1a, 0xc3, 0xb4, 0xfe, 0x1d, 0xa0, 0xa6, 0x30, + 0x56, 0x9c, 0xf9, 0x9f, 0x33, 0x28, 0xd2, 0xf4, 0xee, 0xe0, 0xe9, 0x5e, + 0x3a, 0xde, 0x5b, 0xaf, 0xae, 0xba, 0x44, 0xf9, 0xd8, 0x92, 0xf2, 0x98, + 0xb9, 0x86, 0x2b, 0x99, 0x20, 0x4e, 0xce, 0xf3, 0x20, 0x4d, 0xa8, 0x1, + 0xb1, 0xd, 0x7d, 0x57, 0xf, 0x3d, 0x5f, 0xb9, 0x71, 0xe2, 0x11, 0x96, + 0xa0, 0x38, 0xd8, 0x67, 0x17, 0xaf, 0x9a, 0xdf, 0x4b, 0xd1, 0x1e, 0x46, + 0x7e, 0x5, 0xb, 0x87, 0x25, 0xd7, 0xa, 0x18, 0xef, 0xb0, 0x23, 0xbf, + 0xc2, 0x3, 0xbc, 0x8a, 0xef, 0x4f, 0x8f, 0x26, 0x59, 0xcc, 0xee, 0xdb, + 0x80, 0xfe, 0xe2, 0x45, 0x52, 0xca, 0x52, 0xf3, 0x2d, 0x9c, 0xbd, 0xe4, + 0xe5, 0x6b, 0xb6, 0x70, 0x45, 0xaa, 0x77, 0x1c, 0xed, 0x5b, 0x66, 0x8e, + 0x96, 0x38, 0xf9, 0xeb, 0x4, 0x9a, 0x6d, 0xaa, 0x8e, 0x6e, 0xea, 0xff, + 0x52, 0x6c, 0x23, 0xce, 0x66, 0xa0, 0x7d, 0x7a, 0xf1, 0x1b, 0xbb, 0x80, + 0xce, 0x5b, 0xf5, 0x75, 0x5a, 0x69, 0xbe, 0x8b, 0x3e, 0xe2, 0x54, 0xe, + 0x1, 0xff, 0x28, 0x6c, 0xf9, 0xe8, 0xff, 0x79, 0x99, 0xf3, 0xd5, 0x57, + 0x1e, 0xff, 0xf7, 0x7d, 0x4a, 0x96, 0xd5, 0xf8, 0xd, 0x74, 0x74, 0xa7, + 0x44, 0x28, 0x4e, 0x51, 0x68, 0xe5, 0x36, 0x2b, 0x5e, 0x34, 0x54, 0x2a, + 0xdb, 0x1b, 0x2b, 0xcf, 0xb2, 0x3, 0x4c, 0xfa, 0x83, 0xbb, 0x8b, 0xb1, + 0xc0, 0x45, 0xcc, 0xca, 0xc2, 0xf2, 0x18, 0xab, 0x27, 0x7d, 0x10, 0x6e, + 0xbd, 0x2e, 0xa4, 0xe, 0xea, 0xe1, 0xe0, 0x2f, 0x69, 0x3, 0xa8, 0x57, + 0xcc, 0x24, 0x53, 0x36, 0x4b, 0xb, 0xf2, 0x26, 0xcf, 0x62, 0x47, 0x65, + 0xbe, 0x41, 0x10, 0x16, 0xa4, 0xec, 0xfb, 0x49, 0xd1, 0x92, 0x39, 0x56, + 0x49, 0x50, 0x30, 0x87, 0x3a, 0x4f, 0xf6, 0x1e, 0xe8, 0xe2, 0x8f, 0xd6, + 0x86, 0xab, 0x17, 0x5a, 0xe0, 0x1d, 0xca, 0xec, 0x69, 0xe9, 0x71, 0xa, + 0x6, 0xe9, 0x20, 0x0, 0xac, 0x46, 0x7b, 0xf3, 0xed, 0x88, 0x83, 0x77, + 0x8c, 0x7a, 0xaf, 0xc6, 0x9c, 0xf8, 0xe9, 0xc3, 0x9b, 0xc0, 0xec, 0x62, + 0x76, 0x2a, 0xab, 0x34, 0xd7, 0x64, 0xd9, 0x50, 0x7c, 0x73, 0x1e, 0xe4, + 0xf0, 0xdd, 0xce, 0x26, 0xfa, 0x25, 0x46, 0xd3, 0xfc, 0x87, 0x9b, 0x2c, + 0xcc, 0x3f, 0xf2, 0x9d, 0x60, 0x44, 0x97, 0x85, 0xfb, 0x73, 0xee, 0xdd, + 0xe0, 0xb1, 0xca, 0x77, 0x72, 0xb0, 0x24, 0xd3, 0xff, 0xc6, 0xd3, 0x57, + 0xa0, 0xed, 0xcc, 0x52, 0x70, 0x53, 0xab, 0xbe, 0xf8, 0x40, 0xca, 0x79, + 0x9b, 0x3b, 0x5e, 0xc8, 0xd1, 0x9f, 0x30, 0xe6, 0xa, 0x87, 0x71, 0xc4, + 0xa8, 0x83, 0x9c, 0xa4, 0x64, 0x3b, 0x6f, 0x8c, 0xd6, 0x7e, 0xa0, 0xdf, + 0x68, 0x20, 0xe2, 0xf6, 0x4b, 0xa0, 0x97, 0xe9, 0xbf, 0x84, 0x92, 0xde, + 0x14, 0xb2, 0x48, 0x6d, 0x2, 0xad, 0x2b, 0x2b, 0x32, 0xf8, 0xb8, 0xd5, + 0xad, 0x1a, 0x26, 0x1, 0x39, 0x87, 0xbc, 0x29, 0xf7, 0x61, 0xf7, 0x7b, + 0x27, 0xa0, 0x86, 0xbb, 0xb7, 0x54, 0xd5, 0x18, 0x3, 0xad, 0x25, 0xe7, + 0xaf, 0x5, 0x20, 0xb8, 0xc0, 0xd7, 0x52, 0x5a, 0x14, 0x7, 0x62, 0xb1, + 0x89, 0x39, 0x18, 0x14, 0x7e, 0x5b, 0x91, 0xaf, 0x60, 0xfa, 0x33, 0xec, + 0x9d, 0xe4, 0x5e, 0x92, 0x26, 0xc4, 0x8d, 0xf0, 0x86, 0x78, 0xaf, 0x16, + 0x98, 0x98, 0x15, 0xa5, 0xae, 0x1a, 0xf9, 0x71, 0xba, 0x13, 0xb6, 0xe1, + 0x54, 0x71, 0xf7, 0xd3, 0xa3, 0x6, 0xbb, 0x11, 0x6b, 0x55, 0xd, 0xc3, + 0x7f, 0xe4, 0x88, 0x80, 0x64, 0x30, 0x11, 0x94, 0xb9, 0x75, 0x8e, 0xd9, + 0x68, 0x40, 0xbb, 0x6a, 0x32, 0xfa, 0xbb, 0x45, 0x44, 0xc7, 0xf2, 0x12, + 0x54, 0xca, 0x5b, 0xc3, 0x2a, 0xd6, 0x45, 0x2b, 0xeb, 0x8b, 0xd3, 0xff, + 0x5f, 0xcb, 0x38, 0x38, 0xa1, 0xe8, 0xef, 0xdd, 0x5, 0x2a, 0xf8, 0xb, + 0xa8, 0x5e, 0x6, 0x22, 0x23, 0xdd, 0xcf, 0x51, 0xbe, 0x3d, 0xb1, 0x49, + 0xb5, 0xf, 0xda, 0x35, 0xfa, 0x5, 0xef, 0x7, 0x25, 0x8, 0x55, 0x16, + 0x80, 0xd5, 0xe7, 0xf8, 0xc6, 0xaf, 0xf9, 0x53, 0x23, 0x73, 0x9c, 0x8b, + 0xd5, 0x37, 0x24, 0x4b, 0xf6, 0xfb, 0xad, 0xb1, 0x38, 0x43, 0x21, 0xaf, + 0xf2, 0x3f, 0xb4, 0x6f, 0xb6, 0x84, 0x93, 0x89, 0x91, 0x83, 0x2, 0xf3, + 0x6c, 0x4e, 0xb, 0x94, 0xa1, 0xe2, 0xad, 0xa5, 0xfc, 0x93, 0xcb, 0x15, + 0xe1, 0x92, 0x9a, 0xc1, 0xc1, 0xf2, 0x8, 0xb5, 0x89, 0xf2, 0x90, 0x0, + 0x8a, 0x82, 0xcd, 0x69, 0x4b, 0xec, 0x21, 0xd0, 0x70, 0x2e, 0xe, 0x4f, + 0x34, 0xe3, 0x32, 0xb1, 0x66, 0x83, 0x9b, 0xd5, 0x12, 0x63, 0x1c, 0xa1, + 0x4, 0xde, 0x7e, 0xa0, 0xe8, 0x1b, 0x2a, 0xd7, 0xf5, 0xa3, 0x75, 0xfb, + 0xa9, 0x40, 0x36, 0x6d, +}; +const size_t kAltGameImages2xOffsets[] = { + 0, 537, 3493, 6682, 10085, 11884, +}; +const size_t kAltGameImages2xSizes[] = { + 537, 2956, 3189, 3403, 1799, 2436, }; constexpr int kAltGameImagesCount = 6; -std::string DecryptImage(const std::string& image_ciphertext, - crypto::SymmetricKey* key) { +static_assert(kAltGameImagesCount == base::size(kAltGameImages1xOffsets), ""); +static_assert(kAltGameImagesCount == base::size(kAltGameImages1xSizes), ""); +static_assert(kAltGameImagesCount == base::size(kAltGameImages2xOffsets), ""); +static_assert(kAltGameImagesCount == base::size(kAltGameImages2xSizes), ""); + +bool DecryptImage(base::span<const uint8_t> image_ciphertext, + crypto::SymmetricKey* key, + std::vector<uint8_t>* out) { constexpr int kBlockSize = 16; crypto::Encryptor encryptor; // *Never* use this pattern for encrypting anything that matters! There are @@ -2779,28 +1866,10 @@ if (!encryptor.Init(key, crypto::Encryptor::Mode::CBC, /*iv=*/key->key().substr(0, kBlockSize))) { DLOG(ERROR) << "Failed to initialize encryptor."; - return std::string(); + return false; } - 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(kAltGameImages1x[id], kAltGameImages1xLength[id]); - else if (scale == 2) - *image = std::string(kAltGameImages2x[id], kAltGameImages2xLength[id]); - else - return false; - return true; + return encryptor.Decrypt(image_ciphertext, out); } std::unique_ptr<crypto::SymmetricKey> GetKey() { @@ -2829,6 +1898,70 @@ return key; } +int ChooseAltGame() { + // Image 0 should be "common". + static_assert(1 <= kAltGameImagesCount - 1, ""); + return base::RandInt(1, kAltGameImagesCount - 1); +} + +bool IsPng(base::span<const uint8_t> data) { + size_t size = sizeof(kPngMagicBytes); + return data.size() >= size && + std::memcmp(data.data(), kPngMagicBytes, size) == 0; +} + +std::string MakeDataUrl(base::span<const uint8_t> image) { + return base::StrCat({"data:image/png;base64,", base::Base64Encode(image)}); +} + +bool GetImagesInternal(crypto::SymmetricKey* key, + int choice, + base::span<const uint8_t> encrypted_images, + const size_t offsets[], + const size_t sizes[], + std::string* common_result, + std::string* specific_result) { + std::vector<uint8_t> images; + if (!DecryptImage(encrypted_images, key, &images)) { + DLOG(ERROR) << "Failed to decrypt alt game images."; + return false; + } + + // Decompress in place. + base::span<uint8_t> compressed_images(images); + images.resize(compression::GetUncompressedSize(images)); + if (!compression::GzipUncompress(compressed_images, images)) { + DLOG(ERROR) << "Failed to decompress alt game images."; + return false; + } + + base::span<const uint8_t> images_span(images); + base::span<const uint8_t> raw_common = + images_span.subspan(offsets[0], sizes[0]); + base::span<const uint8_t> raw_specific = + images_span.subspan(offsets[choice], sizes[choice]); + if (!IsPng(raw_common) || !IsPng(raw_specific)) { + DLOG(ERROR) << "Alt game images missing PNG magic bytes."; + return false; + } + + *common_result = MakeDataUrl(raw_common); + *specific_result = MakeDataUrl(raw_specific); + return true; +} + +bool GetImages1x(crypto::SymmetricKey* key, int choice, AltGameImages* result) { + return GetImagesInternal(key, choice, kAltGameImages1x, + kAltGameImages1xOffsets, kAltGameImages1xSizes, + &result->common_1x, &result->specific_1x); +} + +bool GetImages2x(crypto::SymmetricKey* key, int choice, AltGameImages* result) { + return GetImagesInternal(key, choice, kAltGameImages2x, + kAltGameImages2xOffsets, kAltGameImages2xSizes, + &result->common_2x, &result->specific_2x); +} + } // namespace const base::Feature kNetErrorAltGameMode{"NetErrorAltGameMode", @@ -2840,39 +1973,20 @@ 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(); - } +bool GetAltGameImages(AltGameImages* result, int* choice) { + *choice = ChooseAltGame(); std::unique_ptr<crypto::SymmetricKey> key = GetKey(); if (!key) { DLOG(ERROR) << "Failed to load alt game image encryption key."; - return std::string(); + return false; } - 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; + return GetImages1x(key.get(), *choice, result) && + GetImages2x(key.get(), *choice, result); } -int ChooseAltGame() { - // Image 0 should be "common". - static_assert(1 <= kAltGameImagesCount - 1, ""); - return base::RandInt(1, kAltGameImagesCount - 1); -} +AltGameImages::AltGameImages() = default; +AltGameImages::~AltGameImages() = default; } // namespace error_page
diff --git a/components/error_page/common/alt_game_images.h b/components/error_page/common/alt_game_images.h index d6677f2c3..df16aaf1d 100644 --- a/components/error_page/common/alt_game_images.h +++ b/components/error_page/common/alt_game_images.h
@@ -17,11 +17,20 @@ // Gets the value of kNetErrorAltGameMode. bool EnableAltGameMode(); -// Returns a data URL corresponding to the image ID and scale. -std::string GetAltGameImage(int image_id, int scale); +// Image loading result. +struct AltGameImages { + std::string common_1x; + std::string specific_1x; + std::string common_2x; + std::string specific_2x; -// Returns an image ID. -int ChooseAltGame(); + AltGameImages(); + ~AltGameImages(); +}; + +// Load images into |result| and game type into |choice|. Returns true on +// success. +bool GetAltGameImages(AltGameImages* result, int* choice); } // namespace error_page
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc index 99c0d0f..d057235 100644 --- a/components/error_page/common/localized_error.cc +++ b/components/error_page/common/localized_error.cc
@@ -930,19 +930,23 @@ l10n_util::GetStringUTF16(IDS_ERRORPAGE_DINO_GAME_START)); if (EnableAltGameMode()) { - result.strings.SetBoolean("enableAltGameMode", true); // We don't know yet which scale the page will use, so both 1x and 2x // should be loaded. - result.strings.SetString("altGameCommonImage1x", - GetAltGameImage(/*image_id=*/0, /*scale=*/1)); - result.strings.SetString("altGameCommonImage2x", - GetAltGameImage(/*image_id=*/0, /*scale=*/2)); - int choice = ChooseAltGame(); - result.strings.SetString("altGameType", base::NumberToString(choice)); - result.strings.SetString("altGameSpecificImage1x", - GetAltGameImage(choice, 1)); - result.strings.SetString("altGameSpecificImage2x", - GetAltGameImage(choice, 2)); + AltGameImages images; + int alt_game_choice; + if (GetAltGameImages(&images, &alt_game_choice)) { + result.strings.SetBoolean("enableAltGameMode", true); + result.strings.SetString("altGameType", + base::NumberToString(alt_game_choice)); + result.strings.SetStringPath("altGameCommonImage1x", + std::move(images.common_1x)); + result.strings.SetStringPath("altGameCommonImage2x", + std::move(images.common_2x)); + result.strings.SetStringPath("altGameSpecificImage1x", + std::move(images.specific_1x)); + result.strings.SetStringPath("altGameSpecificImage2x", + std::move(images.specific_2x)); + } } }
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h index db006b9..940b5f8 100644 --- a/components/infobars/core/infobar_delegate.h +++ b/components/infobars/core/infobar_delegate.h
@@ -171,7 +171,7 @@ LITE_MODE_HTTPS_IMAGE_COMPRESSION_INFOBAR_ANDROID = 100, // Removed: SYSTEM_INFOBAR_DELEGATE_MAC = 101, EXPERIMENTAL_INFOBAR_DELEGATE_LACROS = 102, - ROSETTA_REQUIRED_INFOBAR_DELEGATE = 103, + // Removed: ROSETTA_REQUIRED_INFOBAR_DELEGATE = 103, // Removed: WEBID_PERMISSION_INFOBAR_DELEGATE = 104, AUTOFILL_OFFER_NOTIFICATION_INFOBAR_DELEGATE = 105, AUTOFILL_ADDRESS_PROFILE_INFOBAR_DELEGATE_IOS = 106,
diff --git a/components/page_info/page_info_ui.cc b/components/page_info/page_info_ui.cc index 813a302..44768286 100644 --- a/components/page_info/page_info_ui.cc +++ b/components/page_info/page_info_ui.cc
@@ -844,6 +844,7 @@ // not visible to the user, so don't affect Page Info. break; + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kNone: case security_state::SafetyTipStatus::kUnknown: break;
diff --git a/components/paint_preview/common/serial_utils.cc b/components/paint_preview/common/serial_utils.cc index 8fd6f25..e614199 100644 --- a/components/paint_preview/common/serial_utils.cc +++ b/components/paint_preview/common/serial_utils.cc
@@ -76,6 +76,9 @@ sk_sp<SkData> SerializeImage(SkImage* image, void* ctx) { ImageSerializationContext* context = reinterpret_cast<ImageSerializationContext*>(ctx); + if (image->isTextureBacked()) { + return SkData::MakeEmpty(); + } const SkImageInfo& image_info = image->imageInfo(); // If decoding/encoding the image would result in it exceeding the allowable
diff --git a/components/password_manager/core/browser/generation/password_requirements_spec_fetcher_impl.cc b/components/password_manager/core/browser/generation/password_requirements_spec_fetcher_impl.cc index 099649dc..e8117c0 100644 --- a/components/password_manager/core/browser/generation/password_requirements_spec_fetcher_impl.cc +++ b/components/password_manager/core/browser/generation/password_requirements_spec_fetcher_impl.cc
@@ -195,9 +195,10 @@ lookup->download_timer.Stop(); UMA_HISTOGRAM_TIMES("PasswordManager.RequirementsSpecFetcher.NetworkDuration", base::TimeTicks::Now() - lookup->start_of_request); + // Network error codes are negative. See: src/net/base/net_error_list.h. base::UmaHistogramSparse( "PasswordManager.RequirementsSpecFetcher.NetErrorCode", - lookup->url_loader->NetError()); + -lookup->url_loader->NetError()); if (lookup->url_loader->ResponseInfo() && lookup->url_loader->ResponseInfo()->headers) { base::UmaHistogramSparse( @@ -206,8 +207,8 @@ } if (!response_body || lookup->url_loader->NetError() != net::Error::OK) { - VLOG(1) << "Fetch for " << hash_prefix << ": failed to fetch " - << lookup->url_loader->NetError(); + VLOG(1) << "Fetch for " << hash_prefix << ": failed to fetch. Net Error: " + << net::ErrorToString(lookup->url_loader->NetError()); TriggerCallbackToAll(&lookup->callbacks, ResultCode::kErrorFailedToFetch, PasswordRequirementsSpec()); return;
diff --git a/components/password_manager/core/browser/leak_detection/encryption_utils.cc b/components/password_manager/core/browser/leak_detection/encryption_utils.cc index 3bf9d44..d8e0d3f5 100644 --- a/components/password_manager/core/browser/leak_detection/encryption_utils.cc +++ b/components/password_manager/core/browser/leak_detection/encryption_utils.cc
@@ -23,17 +23,17 @@ namespace { -template <typename StringT> -StringT CanonicalizeUsernameT(base::BasicStringPiece<StringT> username) { - // String literal containing a single period (i.e. "."). Spelt out explicitly, - // because there is no short-form syntax for std::u16string. - static constexpr typename StringT::value_type kPeriod[] = {'.', '\0'}; +template <typename CharT> +std::basic_string<CharT> CanonicalizeUsernameT( + base::BasicStringPiece<CharT> username) { + static constexpr CharT kPeriod = '.'; - StringT email_lower = base::ToLowerASCII(username); + std::basic_string<CharT> email_lower = base::ToLowerASCII(username); // |email_lower| might be an email address. Strip off the mail-address host, // remove periods from the username and return the result. - StringT user_lower = email_lower.substr(0, email_lower.find_last_of('@')); - base::RemoveChars(user_lower, kPeriod, &user_lower); + std::basic_string<CharT> user_lower = + email_lower.substr(0, email_lower.find_last_of('@')); + base::RemoveChars(user_lower, {&kPeriod, 1}, &user_lower); return user_lower; }
diff --git a/components/password_manager/ios/password_form_helper.mm b/components/password_manager/ios/password_form_helper.mm index 1edda69..8dbfafe 100644 --- a/components/password_manager/ios/password_form_helper.mm +++ b/components/password_manager/ios/password_form_helper.mm
@@ -173,14 +173,16 @@ // origin. return; } - if (!self.delegate || formData.empty()) + if (!self.delegate || formData.empty()) { return; + } std::vector<FormData> forms; NSString* nsFormData = [NSString stringWithUTF8String:formData.c_str()]; autofill::ExtractFormsData(nsFormData, false, std::u16string(), pageURL, pageURL.GetOrigin(), &forms); - if (forms.size() != 1) + if (forms.size() != 1) { return; + } // Extract FieldDataManager data for observed fields. [self extractKnownFieldData:forms[0]]; @@ -233,8 +235,9 @@ return; } // Extract FieldDataManager data for observed form fields. - for (FormData& form : formsData) + for (FormData& form : formsData) { [self extractKnownFieldData:form]; + } *forms = std::move(formsData); } @@ -280,11 +283,13 @@ // Find the maximum extracted value. uint32_t maxID = 0; for (const auto& form : forms) { - if (form.unique_renderer_id) + if (form.unique_renderer_id) { maxID = std::max(maxID, form.unique_renderer_id.value()); + } for (const auto& field : form.fields) { - if (field.unique_renderer_id) + if (field.unique_renderer_id) { maxID = std::max(maxID, field.unique_renderer_id.value()); + } } } completionHandler(forms, maxID);
diff --git a/components/password_manager/ios/shared_password_controller.mm b/components/password_manager/ios/shared_password_controller.mm index 25d9e04..57db18d 100644 --- a/components/password_manager/ios/shared_password_controller.mm +++ b/components/password_manager/ios/shared_password_controller.mm
@@ -123,7 +123,10 @@ // Form data for password generation on this page. std::map<FormRendererId, PasswordFormGenerationData> _formGenerationData; + // Identifier of the field that was last typed into. FieldRendererId _lastTypedfieldIdentifier; + + // The value that was last typed by the user. NSString* _lastTypedValue; // Identifier of the last focused form. @@ -185,11 +188,13 @@ - (void)webState:(web::WebState*)webState didFinishNavigation:(web::NavigationContext*)navigation { DCHECK_EQ(_webState, webState); - if (!navigation->HasCommitted() || navigation->IsSameDocument()) + if (!navigation->HasCommitted() || navigation->IsSameDocument()) { return; + } - if (!GetPageURLAndCheckTrustLevel(webState, nullptr)) + if (!GetPageURLAndCheckTrustLevel(webState, nullptr)) { return; + } auto fieldDataManager = UniqueIDDataTabHelper::FromWebState(_webState)->GetFieldDataManager(); @@ -213,11 +218,13 @@ // Retrieve the identity of the page. In case the page might be malicous, // returns early. GURL pageURL; - if (!GetPageURLAndCheckTrustLevel(webState, &pageURL)) + if (!GetPageURLAndCheckTrustLevel(webState, &pageURL)) { return; + } - if (!web::UrlHasWebScheme(pageURL)) + if (!web::UrlHasWebScheme(pageURL)) { return; + } if (webState->ContentIsHTML()) { [self findPasswordFormsAndSendThemToPasswordStore]; @@ -235,8 +242,9 @@ frameDidBecomeAvailable:(web::WebFrame*)web_frame { DCHECK_EQ(_webState, webState); DCHECK(web_frame); - if (!web_frame->CanCallJavaScriptFunction()) + if (!web_frame->CanCallJavaScriptFunction()) { return; + } UniqueIDDataTabHelper* uniqueIDDataTabHelper = UniqueIDDataTabHelper::FromWebState(_webState); uint32_t nextAvailableRendererID = @@ -249,10 +257,12 @@ - (void)webState:(web::WebState*)webState frameWillBecomeUnavailable:(web::WebFrame*)web_frame { // No need to try to detect submissions when the webState is being destroyed. - if (webState->IsBeingDestroyed()) + if (webState->IsBeingDestroyed()) { return; - if (web_frame->IsMainFrame() || !web_frame->CanCallJavaScriptFunction()) + } + if (web_frame->IsMainFrame() || !web_frame->CanCallJavaScriptFunction()) { return; + } _passwordManager->OnIframeDetach(web_frame->GetFrameId(), _delegate.passwordManagerDriver, *self.formHelper.fieldDataManager); @@ -283,8 +293,9 @@ webState:(web::WebState*)webState completionHandler: (SuggestionsAvailableCompletion)completion { - if (!GetPageURLAndCheckTrustLevel(webState, nullptr)) + if (!GetPageURLAndCheckTrustLevel(webState, nullptr)) { return; + } [self.suggestionHelper checkIfSuggestionsAvailableForForm:formQuery isMainFrame:isMainFrame @@ -339,8 +350,9 @@ - (void)retrieveSuggestionsForForm:(FormSuggestionProviderQuery*)formQuery webState:(web::WebState*)webState completionHandler:(SuggestionsReadyCompletion)completion { - if (!GetPageURLAndCheckTrustLevel(webState, nullptr)) + if (!GetPageURLAndCheckTrustLevel(webState, nullptr)) { return; + } NSArray<FormSuggestion*>* rawSuggestions = [self.suggestionHelper retrieveSuggestionsWithFormID:formQuery.uniqueFormID fieldIdentifier:formQuery.uniqueFieldID @@ -373,9 +385,9 @@ requiresReauth:requiresReauth]; [suggestions addObject:suggestion]; } - base::Optional<PasswordDropdownState> suggestion_state; + base::Optional<PasswordDropdownState> suggestionState; if (suggestions.count) { - suggestion_state = PasswordDropdownState::kStandard; + suggestionState = PasswordDropdownState::kStandard; } if ([self canGeneratePasswordForForm:formQuery.uniqueFormID @@ -391,11 +403,11 @@ requiresReauth:NO]; [suggestions addObject:suggestion]; - suggestion_state = PasswordDropdownState::kStandardGenerate; + suggestionState = PasswordDropdownState::kStandardGenerate; } - if (suggestion_state) { - LogPasswordDropdownShown(*suggestion_state, [self isIncognito]); + if (suggestionState) { + LogPasswordDropdownShown(*suggestionState, [self isIncognito]); } completion([suggestions copy], self); @@ -514,8 +526,9 @@ - (void)didFinishPasswordFormExtraction:(const std::vector<FormData>&)forms withMaxUniqueID:(uint32_t)maxID { // Do nothing if |self| has been detached. - if (!_passwordManager) + if (!_passwordManager) { return; + } if (!forms.empty()) { [self.suggestionHelper updateStateOnPasswordFormExtracted]; @@ -556,19 +569,22 @@ fieldIdentifier:(FieldRendererId)fieldIdentifier fieldType:(NSString*)fieldType { if ([self isIncognito] || !self.passwordGenerationHelper->IsGenerationEnabled( - /*log_debug_data*/ true)) + /*log_debug_data*/ true)) { return NO; + } if (![fieldType isEqual:kPasswordFieldType]) return NO; - const PasswordFormGenerationData* generation_data = + const PasswordFormGenerationData* generationData = [self formForGenerationFromFormID:formIdentifier]; - if (!generation_data) + if (!generationData) { return NO; + } FieldRendererId newPasswordIdentifier = - generation_data->new_password_renderer_id; - if (fieldIdentifier == newPasswordIdentifier) + generationData->new_password_renderer_id; + if (fieldIdentifier == newPasswordIdentifier) { return YES; + } // Don't show password generation if the field is 'confirm password'. return NO; @@ -595,11 +611,11 @@ !generationData || generationData->new_password_renderer_id != fieldIdentifier; if (isManuallyTriggered && shouldUpdateGenerationData) { - PasswordFormGenerationData generation_data = { + PasswordFormGenerationData generationData = { .form_renderer_id = formIdentifier, .new_password_renderer_id = fieldIdentifier, }; - [self formEligibleForGenerationFound:generation_data]; + [self formEligibleForGenerationFound:generationData]; } // TODO(crbug.com/886583): pass correct |max_length|. @@ -642,14 +658,15 @@ - (void)injectGeneratedPasswordForFormId:(FormRendererId)formIdentifier generatedPassword:(NSString*)generatedPassword completionHandler:(void (^)())completionHandler { - const autofill::PasswordFormGenerationData* generation_data = + const autofill::PasswordFormGenerationData* generationData = [self formForGenerationFromFormID:formIdentifier]; - if (!generation_data) + if (!generationData) { return; + } FieldRendererId newPasswordUniqueId = - generation_data->new_password_renderer_id; + generationData->new_password_renderer_id; FieldRendererId confirmPasswordUniqueId = - generation_data->confirmation_password_renderer_id; + generationData->confirmation_password_renderer_id; auto generatedPasswordInjected = ^(BOOL success) { auto passwordPresaved = ^(BOOL found, const autofill::FormData& form) { @@ -667,8 +684,9 @@ self.isPasswordGenerated = YES; self.passwordGeneratedIdentifier = newPasswordUniqueId; } - if (completionHandler) + if (completionHandler) { completionHandler(); + } }; [self.formHelper fillPasswordForm:formIdentifier @@ -700,8 +718,9 @@ // If there's a change in password forms on a page, they should be parsed // again. - if (params.type == "form_changed") + if (params.type == "form_changed") { [self findPasswordFormsAndSendThemToPasswordStore]; + } // If the form was removed, PasswordManager should be informed to decide // whether the form was submitted.
diff --git a/components/permissions/chooser_context_base.cc b/components/permissions/chooser_context_base.cc index b896847..bf6c91f 100644 --- a/components/permissions/chooser_context_base.cc +++ b/components/permissions/chooser_context_base.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings_pattern.h" @@ -62,6 +63,29 @@ return content_setting == CONTENT_SETTING_ASK; } +std::unique_ptr<ChooserContextBase::Object> +ChooserContextBase::GetGrantedObject(const url::Origin& origin, + const base::StringPiece key) { + if (!CanRequestObjectPermission(origin)) + return nullptr; + + content_settings::SettingInfo info; + base::Value setting = GetWebsiteSetting(origin, &info); + + base::Value* objects = setting.FindListKey(kObjectListKey); + if (!objects) + return nullptr; + + for (auto& object : objects->GetList()) { + if (IsValidObject(object) && GetKeyForObject(object) == key) { + return std::make_unique<Object>( + origin, std::move(object), info.source, + host_content_settings_map_->IsOffTheRecord()); + } + } + return nullptr; +} + std::vector<std::unique_ptr<ChooserContextBase::Object>> ChooserContextBase::GetGrantedObjects(const url::Origin& origin) { if (!CanRequestObjectPermission(origin)) @@ -137,8 +161,25 @@ setting.SetKey(kObjectListKey, base::Value(base::Value::Type::LIST)); } - if (!base::Contains(objects->GetList(), object)) - objects->Append(std::move(object)); + const std::string key = GetKeyForObject(object); + + if (key.empty()) { + // Use the legacy behavior. + if (!base::Contains(objects->GetList(), object)) + objects->Append(std::move(object)); + } else { + base::Value::ListView object_list = objects->GetList(); + auto it = base::ranges::find_if(object_list, [this, &key](auto& obj) { + return IsValidObject(obj) && GetKeyForObject(obj) == key; + }); + if (it != object_list.end()) { + // Update object permission. + *it = std::move(object); + } else { + // Grant object permission. + objects->Append(std::move(object)); + } + } SetWebsiteSetting(origin, std::move(setting)); NotifyPermissionChanged(); @@ -180,6 +221,35 @@ NotifyPermissionRevoked(origin); } +void ChooserContextBase::RevokeObjectPermission(const url::Origin& origin, + const base::StringPiece key) { + base::Value setting = GetWebsiteSetting(origin, /*info=*/nullptr); + base::Value* objects = setting.FindListKey(kObjectListKey); + if (!objects) + return; + + base::Value::ListView object_list = objects->GetList(); + auto it = base::ranges::find_if(object_list, [this, &key](auto& object) { + return IsValidObject(object) && GetKeyForObject(object) == key; + }); + if (it != object_list.end()) + objects->EraseListIter(it); + + SetWebsiteSetting(origin, std::move(setting)); + NotifyPermissionRevoked(origin); +} + +bool ChooserContextBase::HasGrantedObjects(const url::Origin& origin) { + base::Value setting = GetWebsiteSetting(origin, /*info=*/nullptr); + base::Value* objects = setting.FindListKey(kObjectListKey); + + return objects && !objects->GetList().empty(); +} + +std::string ChooserContextBase::GetKeyForObject(const base::Value& object) { + return std::string(); +} + bool ChooserContextBase::IsOffTheRecord() { return host_content_settings_map_->IsOffTheRecord(); }
diff --git a/components/permissions/chooser_context_base.h b/components/permissions/chooser_context_base.h index f5169b5..35259de9 100644 --- a/components/permissions/chooser_context_base.h +++ b/components/permissions/chooser_context_base.h
@@ -71,6 +71,15 @@ // by default but could be set by the user or group policy. bool CanRequestObjectPermission(const url::Origin& origin); + // Returns the object corresponding to |key| that |origin| has been granted + // permission to access. This method should only be called if + // |GetKeyForObject()| is overridden to return sensible keys. + // + // This method may be extended by a subclass to return + // objects not stored in |host_content_settings_map_|. + virtual std::unique_ptr<Object> GetGrantedObject(const url::Origin& origin, + const base::StringPiece key); + // Returns the list of objects that |origin| has been granted permission to // access. This method may be extended by a subclass to return objects not // stored in |host_content_settings_map_|. @@ -86,6 +95,9 @@ // Grants |origin| access to |object| by writing it into // |host_content_settings_map_|. + // TODO(https://crbug.com/1189682): Combine GrantObjectPermission and + // UpdateObjectPermission methods into key-based GrantOrUpdateObjectPermission + // once backend is updated to make key-based methods more efficient. void GrantObjectPermission(const url::Origin& origin, base::Value object); // Updates |old_object| with |new_object| for |origin|, and writes the value @@ -99,9 +111,36 @@ // This method may be extended by a subclass to revoke permission to access // objects returned by GetGrantedObjects but not stored in // |host_content_settings_map_|. + // TODO(https://crbug.com/1189682): Remove this method once backend is updated + // to make key-based methods more efficient. virtual void RevokeObjectPermission(const url::Origin& origin, const base::Value& object); + // Revokes |origin|'s permission to access the object corresponding to |key|. + // This method should only be called if |GetKeyForObject()| is overridden to + // return sensible keys. + // + // This method may be extended by a subclass to revoke permission to access + // objects returned by GetGrantedObjects but not stored in + // |host_content_settings_map_|. + virtual void RevokeObjectPermission(const url::Origin& origin, + const base::StringPiece key); + + // Returns whether |origin| has granted objects. + // + // This method may be extended by a subclass to include permission to access + // objects returned by GetGrantedObjects but not stored in + // |host_content_settings_map_|. + virtual bool HasGrantedObjects(const url::Origin& origin); + + // Returns a string which is used to uniquely identify this object. If this + // method is extended by a subclass to return unique keys, the new key-based + // techniques will be used. Otherwise, class methods will fall back to the + // legacy behavior of matching via an object. + // TODO(https://crbug.com/1189682): This should be made fully virtual once + // backend is updated to make key-based methods more efficient. + virtual std::string GetKeyForObject(const base::Value& object); + // Validates the structure of an object read from // |host_content_settings_map_|. virtual bool IsValidObject(const base::Value& object) = 0;
diff --git a/components/permissions/chooser_context_base_unittest.cc b/components/permissions/chooser_context_base_unittest.cc index 4b3b23df..819a079 100644 --- a/components/permissions/chooser_context_base_unittest.cc +++ b/components/permissions/chooser_context_base_unittest.cc
@@ -4,6 +4,7 @@ #include "components/permissions/chooser_context_base.h" +#include "base/strings/strcat.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/permissions/test/chooser_context_base_mock_permission_observer.h" #include "components/permissions/test/test_permissions_client.h" @@ -20,15 +21,23 @@ const char* kRequiredKey1 = "key-1"; const char* kRequiredKey2 = "key-2"; -class TestChooserContext : public ChooserContextBase { +// TODO(https://crbug.com/1189682): For as long as we support object-based +// methods and extending GetKeyForObject is optional for base classes, this file +// will be a bit complicated. +// Currently: +// - object-based methods are TYPED_TESTs (GetKeyForObject extended/not) +// - key-based methods are TEST_Fs which only use TestKeyedChooserContext +// Once object-based methods are removed, typed tests will no longer be needed. + +class TestNoKeyChooserContext : public ChooserContextBase { public: // This class uses the USB content settings type for testing purposes only. - explicit TestChooserContext(content::BrowserContext* browser_context) + explicit TestNoKeyChooserContext(content::BrowserContext* browser_context) : ChooserContextBase( ContentSettingsType::USB_GUARD, ContentSettingsType::USB_CHOOSER_DATA, PermissionsClient::Get()->GetSettingsMap(browser_context)) {} - ~TestChooserContext() override {} + ~TestNoKeyChooserContext() override = default; bool IsValidObject(const base::Value& object) override { return object.DictSize() == 2 && object.FindKey(kRequiredKey1) && @@ -40,6 +49,30 @@ } }; +class TestKeyedChooserContext : public ChooserContextBase { + public: + // This class uses the USB content settings type for testing purposes only. + explicit TestKeyedChooserContext(content::BrowserContext* browser_context) + : ChooserContextBase( + ContentSettingsType::USB_GUARD, + ContentSettingsType::USB_CHOOSER_DATA, + PermissionsClient::Get()->GetSettingsMap(browser_context)) {} + ~TestKeyedChooserContext() override = default; + + bool IsValidObject(const base::Value& object) override { + return object.DictSize() == 2 && object.FindKey(kRequiredKey1) && + object.FindKey(kRequiredKey2); + } + + std::u16string GetObjectDisplayName(const base::Value& object) override { + return {}; + } + + std::string GetKeyForObject(const base::Value& object) override { + return *object.FindStringKey(kRequiredKey1); + } +}; + } // namespace class ChooserContextBaseTest : public testing::Test { @@ -57,7 +90,7 @@ object2_.SetStringKey(kRequiredKey2, "value4"); } - ~ChooserContextBaseTest() override {} + ~ChooserContextBaseTest() override = default; content::BrowserContext* browser_context() { return &browser_context_; } @@ -75,17 +108,202 @@ base::Value object2_; }; -TEST_F(ChooserContextBaseTest, GrantAndRevokeObjectPermissions) { - TestChooserContext context(browser_context()); +template <typename T> +class ChooserContextBaseTypedTest : public ChooserContextBaseTest { + public: + ChooserContextBaseTypedTest() + : ChooserContextBaseTest(), chooser_context_(browser_context()) {} + + ~ChooserContextBaseTypedTest() override = default; + + protected: + T chooser_context_; +}; + +using TestChooserContext = + testing::Types<TestNoKeyChooserContext, TestKeyedChooserContext>; + +TYPED_TEST_SUITE(ChooserContextBaseTypedTest, TestChooserContext); + +// ----------------------------OBJECT-BASED METHODS----------------------------- + +TYPED_TEST(ChooserContextBaseTypedTest, GrantAndRevokeObjectPermissions) { + MockPermissionObserver mock_observer; + this->chooser_context_.AddObserver(&mock_observer); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object1_.Clone()); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object2_.Clone()); + + auto objects = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_EQ(2u, objects.size()); + EXPECT_EQ(this->object1_, objects[0]->value); + EXPECT_EQ(this->object2_, objects[1]->value); + + // Granting permission to one origin should not grant them to another. + objects = this->chooser_context_.GetGrantedObjects(this->origin2_); + EXPECT_EQ(0u, objects.size()); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); + EXPECT_CALL(mock_observer, OnPermissionRevoked(this->origin1_)).Times(2); + this->chooser_context_.RevokeObjectPermission(this->origin1_, this->object1_); + this->chooser_context_.RevokeObjectPermission(this->origin1_, this->object2_); + objects = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_EQ(0u, objects.size()); +} + +TYPED_TEST(ChooserContextBaseTypedTest, GrantObjectPermissionTwice) { + MockPermissionObserver mock_observer; + this->chooser_context_.AddObserver(&mock_observer); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object1_.Clone()); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object1_.Clone()); + + auto objects = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_EQ(1u, objects.size()); + EXPECT_EQ(this->object1_, objects[0]->value); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)); + EXPECT_CALL(mock_observer, OnPermissionRevoked(this->origin1_)); + this->chooser_context_.RevokeObjectPermission(this->origin1_, this->object1_); + objects = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_EQ(0u, objects.size()); +} + +TYPED_TEST(ChooserContextBaseTypedTest, GrantAndUpdateObjectPermission) { + MockPermissionObserver mock_observer; + this->chooser_context_.AddObserver(&mock_observer); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object1_.Clone()); + + auto objects = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_EQ(1u, objects.size()); + EXPECT_EQ(this->object1_, objects[0]->value); + + testing::Mock::VerifyAndClearExpectations(&mock_observer); + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)); + this->chooser_context_.UpdateObjectPermission( + this->origin1_, objects[0]->value, this->object2_.Clone()); + + objects = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_EQ(1u, objects.size()); + EXPECT_EQ(this->object2_, objects[0]->value); +} + +// UpdateObjectPermission() should not grant new permissions. +TYPED_TEST(ChooserContextBaseTypedTest, + UpdateObjectPermissionWithNonExistentPermission) { + MockPermissionObserver mock_observer; + this->chooser_context_.AddObserver(&mock_observer); + + // Attempt to update permission for non-existent |this->object1_| permission. + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(0); + this->chooser_context_.UpdateObjectPermission(this->origin1_, this->object1_, + this->object2_.Clone()); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + + auto objects = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_TRUE(objects.empty()); + + // Grant permission for |this->object2_| but attempt to update permission for + // non-existent |this->object1_| permission again. + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object2_.Clone()); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(0); + this->chooser_context_.UpdateObjectPermission(this->origin1_, this->object1_, + this->object2_.Clone()); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + + objects = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_EQ(1u, objects.size()); + EXPECT_EQ(this->object2_, objects[0]->value); +} + +TYPED_TEST(ChooserContextBaseTypedTest, GetAllGrantedObjects) { + MockPermissionObserver mock_observer; + this->chooser_context_.AddObserver(&mock_observer); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object1_.Clone()); + this->chooser_context_.GrantObjectPermission(this->origin2_, + this->object2_.Clone()); + + auto objects = this->chooser_context_.GetAllGrantedObjects(); + EXPECT_EQ(2u, objects.size()); + EXPECT_EQ(this->object1_, objects[0]->value); + EXPECT_EQ(this->object2_, objects[1]->value); +} + +TYPED_TEST(ChooserContextBaseTypedTest, GetGrantedObjectsWithGuardBlocked) { + auto* map = PermissionsClient::Get()->GetSettingsMap(this->browser_context()); + map->SetContentSettingDefaultScope(this->url1_, this->url1_, + ContentSettingsType::USB_GUARD, + CONTENT_SETTING_BLOCK); + + MockPermissionObserver mock_observer; + this->chooser_context_.AddObserver(&mock_observer); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object1_.Clone()); + this->chooser_context_.GrantObjectPermission(this->origin2_, + this->object2_.Clone()); + + auto objects1 = this->chooser_context_.GetGrantedObjects(this->origin1_); + EXPECT_EQ(0u, objects1.size()); + + auto objects2 = this->chooser_context_.GetGrantedObjects(this->origin2_); + ASSERT_EQ(1u, objects2.size()); + EXPECT_EQ(this->object2_, objects2[0]->value); +} + +TYPED_TEST(ChooserContextBaseTypedTest, GetAllGrantedObjectsWithGuardBlocked) { + auto* map = PermissionsClient::Get()->GetSettingsMap(this->browser_context()); + map->SetContentSettingDefaultScope(this->url1_, this->url1_, + ContentSettingsType::USB_GUARD, + CONTENT_SETTING_BLOCK); + + MockPermissionObserver mock_observer; + this->chooser_context_.AddObserver(&mock_observer); + + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); + this->chooser_context_.GrantObjectPermission(this->origin1_, + this->object1_.Clone()); + this->chooser_context_.GrantObjectPermission(this->origin2_, + this->object2_.Clone()); + + auto objects = this->chooser_context_.GetAllGrantedObjects(); + ASSERT_EQ(1u, objects.size()); + EXPECT_EQ(this->url2_, objects[0]->origin); + EXPECT_EQ(this->object2_, objects[0]->value); +} + +// ------------------------------KEY-BASED METHODS------------------------------ + +TEST_F(ChooserContextBaseTest, GrantAndRevokeObjectPermissions_Keyed) { + TestKeyedChooserContext context(browser_context()); MockPermissionObserver mock_observer; context.AddObserver(&mock_observer); + auto object1_key = context.GetKeyForObject(object1_); + auto object2_key = context.GetKeyForObject(object2_); + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); context.GrantObjectPermission(origin1_, object1_.Clone()); context.GrantObjectPermission(origin1_, object2_.Clone()); - std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = - context.GetGrantedObjects(origin1_); + auto objects = context.GetGrantedObjects(origin1_); EXPECT_EQ(2u, objects.size()); EXPECT_EQ(object1_, objects[0]->value); EXPECT_EQ(object2_, objects[1]->value); @@ -94,16 +312,22 @@ objects = context.GetGrantedObjects(origin2_); EXPECT_EQ(0u, objects.size()); + // Ensure objects can be retrieved individually. + EXPECT_EQ(object1_, context.GetGrantedObject(origin1_, object1_key)->value); + EXPECT_EQ(object2_, context.GetGrantedObject(origin1_, object2_key)->value); + EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); EXPECT_CALL(mock_observer, OnPermissionRevoked(origin1_)).Times(2); - context.RevokeObjectPermission(origin1_, object1_); - context.RevokeObjectPermission(origin1_, object2_); + context.RevokeObjectPermission(origin1_, object1_key); + context.RevokeObjectPermission(origin1_, object2_key); + EXPECT_EQ(nullptr, context.GetGrantedObject(origin1_, object1_key)); + EXPECT_EQ(nullptr, context.GetGrantedObject(origin1_, object2_key)); objects = context.GetGrantedObjects(origin1_); EXPECT_EQ(0u, objects.size()); } -TEST_F(ChooserContextBaseTest, GrantObjectPermissionTwice) { - TestChooserContext context(browser_context()); +TEST_F(ChooserContextBaseTest, GrantObjectPermissionTwice_Keyed) { + TestKeyedChooserContext context(browser_context()); MockPermissionObserver mock_observer; context.AddObserver(&mock_observer); @@ -111,139 +335,44 @@ context.GrantObjectPermission(origin1_, object1_.Clone()); context.GrantObjectPermission(origin1_, object1_.Clone()); - std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = - context.GetGrantedObjects(origin1_); + auto objects = context.GetGrantedObjects(origin1_); EXPECT_EQ(1u, objects.size()); EXPECT_EQ(object1_, objects[0]->value); EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)); EXPECT_CALL(mock_observer, OnPermissionRevoked(origin1_)); - context.RevokeObjectPermission(origin1_, object1_); + context.RevokeObjectPermission(origin1_, context.GetKeyForObject(object1_)); objects = context.GetGrantedObjects(origin1_); EXPECT_EQ(0u, objects.size()); } -TEST_F(ChooserContextBaseTest, GrantAndUpdateObjectPermission) { - TestChooserContext context(browser_context()); +TEST_F(ChooserContextBaseTest, GrantAndUpdateObjectPermission_Keyed) { + TestKeyedChooserContext context(browser_context()); MockPermissionObserver mock_observer; context.AddObserver(&mock_observer); EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)); context.GrantObjectPermission(origin1_, object1_.Clone()); - std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = - context.GetGrantedObjects(origin1_); + auto objects = context.GetGrantedObjects(origin1_); EXPECT_EQ(1u, objects.size()); EXPECT_EQ(object1_, objects[0]->value); + // Update the object without changing the key. + std::string new_value("new_value"); + auto new_object = objects[0]->value.Clone(); + new_object.SetStringKey(kRequiredKey2, new_value); + EXPECT_NE(new_object, objects[0]->value); + testing::Mock::VerifyAndClearExpectations(&mock_observer); EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)); - context.UpdateObjectPermission(origin1_, objects[0]->value, object2_.Clone()); + // GrantObjectPermission will update an object if an object with the same key + // already exists. + context.GrantObjectPermission(origin1_, new_object.Clone()); objects = context.GetGrantedObjects(origin1_); EXPECT_EQ(1u, objects.size()); - EXPECT_EQ(object2_, objects[0]->value); -} - -// UpdateObjectPermission() should not grant new permissions. -TEST_F(ChooserContextBaseTest, - UpdateObjectPermissionWithNonExistentPermission) { - TestChooserContext context(browser_context()); - MockPermissionObserver mock_observer; - context.AddObserver(&mock_observer); - - // Attempt to update permission for non-existent |object1_| permission. - EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(0); - context.UpdateObjectPermission(origin1_, object1_, object2_.Clone()); - testing::Mock::VerifyAndClearExpectations(&mock_observer); - - std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = - context.GetGrantedObjects(origin1_); - EXPECT_TRUE(objects.empty()); - - // Grant permission for |object2_| but attempt to update permission for - // non-existent |object1_| permission again. - EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)); - context.GrantObjectPermission(origin1_, object2_.Clone()); - testing::Mock::VerifyAndClearExpectations(&mock_observer); - - EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(0); - context.UpdateObjectPermission(origin1_, object1_, object2_.Clone()); - testing::Mock::VerifyAndClearExpectations(&mock_observer); -} - -TEST_F(ChooserContextBaseTest, GetAllGrantedObjects) { - TestChooserContext context(browser_context()); - MockPermissionObserver mock_observer; - context.AddObserver(&mock_observer); - - EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); - context.GrantObjectPermission(origin1_, object1_.Clone()); - context.GrantObjectPermission(origin2_, object2_.Clone()); - - std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = - context.GetAllGrantedObjects(); - EXPECT_EQ(2u, objects.size()); - bool found_one = false; - bool found_two = false; - for (const auto& object : objects) { - if (object->origin == url1_) { - EXPECT_FALSE(found_one); - EXPECT_EQ(object1_, objects[0]->value); - found_one = true; - } else if (object->origin == url2_) { - EXPECT_FALSE(found_two); - EXPECT_EQ(object2_, objects[1]->value); - found_two = true; - } else { - ADD_FAILURE() << "Unexpected object."; - } - } - EXPECT_TRUE(found_one); - EXPECT_TRUE(found_two); -} - -TEST_F(ChooserContextBaseTest, GetGrantedObjectsWithGuardBlocked) { - auto* map = PermissionsClient::Get()->GetSettingsMap(browser_context()); - map->SetContentSettingDefaultScope( - url1_, url1_, ContentSettingsType::USB_GUARD, CONTENT_SETTING_BLOCK); - - TestChooserContext context(browser_context()); - MockPermissionObserver mock_observer; - context.AddObserver(&mock_observer); - - EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); - context.GrantObjectPermission(origin1_, object1_.Clone()); - context.GrantObjectPermission(origin2_, object2_.Clone()); - - std::vector<std::unique_ptr<ChooserContextBase::Object>> objects1 = - context.GetGrantedObjects(origin1_); - EXPECT_EQ(0u, objects1.size()); - - std::vector<std::unique_ptr<ChooserContextBase::Object>> objects2 = - context.GetGrantedObjects(origin2_); - ASSERT_EQ(1u, objects2.size()); - EXPECT_EQ(object2_, objects2[0]->value); -} - -TEST_F(ChooserContextBaseTest, GetAllGrantedObjectsWithGuardBlocked) { - auto* map = PermissionsClient::Get()->GetSettingsMap(browser_context()); - map->SetContentSettingDefaultScope( - url1_, url1_, ContentSettingsType::USB_GUARD, CONTENT_SETTING_BLOCK); - - TestChooserContext context(browser_context()); - MockPermissionObserver mock_observer; - context.AddObserver(&mock_observer); - - EXPECT_CALL(mock_observer, OnChooserObjectPermissionChanged(_, _)).Times(2); - context.GrantObjectPermission(origin1_, object1_.Clone()); - context.GrantObjectPermission(origin2_, object2_.Clone()); - - std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = - context.GetAllGrantedObjects(); - ASSERT_EQ(1u, objects.size()); - EXPECT_EQ(url2_, objects[0]->origin); - EXPECT_EQ(object2_, objects[0]->value); + EXPECT_EQ(new_object, objects[0]->value); } } // namespace permissions
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 780252d1..2b467ee 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -25166,6 +25166,30 @@ The order of the list will appear in the same order under the "Order languages based on your preference" section in chrome://settings/languages. Users won't be able to remove or reorder languages set by the policy, but will be able to add languages underneath those set by the policy. Users will also have full control over the browser's UI language and translation/spell check settings, unless enforced by other policies. Leaving the policy unset lets users manipulate the entire list of preferred languages.''', + }, + { + 'name': 'BrowserThemeColor', + 'owners': ['igorruvinov@google.com', 'ydago@google.com', 'pastarmovj@google.com'], + 'type': 'string', + 'schema': { + 'type': 'string', + 'description': '''Hex color which will be used to generate and apply a theme to the browser.''', + }, + 'supported_on': ['chrome.*:91-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'default': None, + 'example_value': '#FFFFFF', + 'id': 840, + 'caption': '''Configure the color of the browser's theme''', + 'tags': [], + 'desc': '''This policy allows admins to configure the color of <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s theme. The input string should be a valid hex color string matching the format "#RRGGBB". + + Setting the policy to a valid hex color causes a theme based on that color to be automatically generated and applied to the browser. Users won't be able to change the theme set by the policy. + + Leaving the policy unset lets users change their browser's theme as preferred.''', } ], 'messages': { @@ -26096,6 +26120,6 @@ 'placeholders': [], 'deleted_policy_ids': [114, 115, 204, 205, 206, 412, 476, 544, 546, 562, 569, 578, 583, 585, 586, 587, 588, 589, 590, 591, 600, 668, 669], 'deleted_atomic_policy_group_ids': [19], - 'highest_id_currently_used': 839, + 'highest_id_currently_used': 840, 'highest_atomic_group_id_currently_used': 40 }
diff --git a/components/policy/resources/webui/policy.html b/components/policy/resources/webui/policy.html index 3889cc3..d731892d 100644 --- a/components/policy/resources/webui/policy.html +++ b/components/policy/resources/webui/policy.html
@@ -8,18 +8,6 @@ <link rel="stylesheet" href="chrome://policy/policy.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> -<if expr="is_ios"> - <!-- TODO(crbug.com/487000): Remove this once injected by web. --> - <script src="chrome://resources/js/ios/web_ui.js"></script> -</if> - -<script src="chrome://resources/js/action_link.js"></script> -<script src="chrome://resources/js/cr.js"></script> -<script src="chrome://resources/js/cr/ui.js"></script> -<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script> -<script src="chrome://resources/js/load_time_data.js"></script> -<script src="chrome://resources/js/assert.js"></script> -<script src="chrome://resources/js/util.js"></script> </head> <body> @@ -215,7 +203,5 @@ </div> </body> -<script src="chrome://policy/strings.js"></script> -<script src="chrome://policy/policy_base.js"></script> -<script src="chrome://policy/policy.js"></script> +<script type="module" src="policy.js"></script> </html>
diff --git a/components/policy/resources/webui/policy.js b/components/policy/resources/webui/policy.js index 7f9a6344..f400fe1 100644 --- a/components/policy/resources/webui/policy.js +++ b/components/policy/resources/webui/policy.js
@@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {Page} from './policy_base.js'; + // Have the main initialization function be called when the page finishes // loading. -document.addEventListener( - 'DOMContentLoaded', - policy.Page.getInstance().initialize.bind(policy.Page.getInstance())); +const page = Page.getInstance(); +document.addEventListener('DOMContentLoaded', () => { + page.initialize(); +});
diff --git a/components/policy/resources/webui/policy_base.js b/components/policy/resources/webui/policy_base.js index 4aeafb3..b2446276 100644 --- a/components/policy/resources/webui/policy_base.js +++ b/components/policy/resources/webui/policy_base.js
@@ -2,686 +2,681 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -cr.define('policy', function() { - /** - * @typedef {{ - * [id: string]: { - * name: string, - * policyNames: !Array<string>, - * }} - */ - let PolicyNamesResponse; +import './strings.m.js'; +import 'chrome://resources/js/action_link.js'; + +// <if expr="is_ios"> +import 'chrome://resources/js/ios/web_ui.js'; +// </if> + +import {addSingletonGetter, addWebUIListener} from 'chrome://resources/js/cr.m.js'; +import {define as crUiDefine} from 'chrome://resources/js/cr/ui.m.js'; +import {FocusOutlineManager} from 'chrome://resources/js/cr/ui/focus_outline_manager.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {$} from 'chrome://resources/js/util.m.js'; + +/** + * @typedef {{ + * [id: string]: { + * name: string, + * policyNames: !Array<string>, + * }} + */ +let PolicyNamesResponse; + +/** + * @typedef {!Array<{ + * name: string, + * id: ?String, + * policies: {[name: string]: policy.Policy} + * }>} + */ +let PolicyValuesResponse; + +/** + * @typedef {{ + * level: string, + * scope: string, + * source: string, + * value: any, + * }} + */ +let Conflict; + +/** + * @typedef {{ + * ignored?: boolean, + * name: string, + * level: string, + * link: ?string, + * scope: string, + * source: string, + * error: string, + * warning: string, + * info: string, + * value: any, + * deprecated: ?boolean, + * future: ?boolean, + * allSourcesMerged: ?boolean, + * conflicts: ?Array<!Conflict>, + * superseded: ?Array<!Conflict>, + * }} + */ +let Policy; + +/** + * @typedef {{ + * id: ?string, + * isExtension?: boolean, + * name: string, + * policies: !Array<!Policy> + * }} + */ +let PolicyTableModel; + +/** + * A box that shows the status of cloud policy for a device, machine or user. + * @constructor + * @extends {HTMLFieldSetElement} + */ +const StatusBox = crUiDefine(function() { + const node = $('status-box-template').cloneNode(true); + node.removeAttribute('id'); + return node; +}); + +StatusBox.prototype = { + // Set up the prototype chain. + __proto__: HTMLFieldSetElement.prototype, /** - * @typedef {!Array<{ - * name: string, - * id: ?String, - * policies: {[name: string]: policy.Policy} - * }>} + * Initialization function for the cr.ui framework. */ - let PolicyValuesResponse; + decorate() {}, /** - * @typedef {{ - * level: string, - * scope: string, - * source: string, - * value: any, - * }} + * Sets the text of a particular named label element in the status box + * and updates the visibility if needed. + * @param {string} labelName The name of the label element that is being + * updated. + * @param {string} labelValue The new text content for the label. + * @param {boolean=} needsToBeShown True if we want to show the label + * False otherwise. */ - let Conflict; - - /** - * @typedef {{ - * ignored?: boolean, - * name: string, - * level: string, - * link: ?string, - * scope: string, - * source: string, - * error: string, - * warning: string, - * info: string, - * value: any, - * deprecated: ?boolean, - * future: ?boolean, - * allSourcesMerged: ?boolean, - * conflicts: ?Array<!Conflict>, - * superseded: ?Array<!Conflict>, - * }} - */ - let Policy; - - /** - * @typedef {{ - * id: ?string, - * isExtension?: boolean, - * name: string, - * policies: !Array<!Policy> - * }} - */ - let PolicyTableModel; - - /** - * A box that shows the status of cloud policy for a device, machine or user. - * @constructor - * @extends {HTMLFieldSetElement} - */ - const StatusBox = cr.ui.define(function() { - const node = $('status-box-template').cloneNode(true); - node.removeAttribute('id'); - return node; - }); - - StatusBox.prototype = { - // Set up the prototype chain. - __proto__: HTMLFieldSetElement.prototype, - - /** - * Initialization function for the cr.ui framework. - */ - decorate() {}, - - /** - * Sets the text of a particular named label element in the status box - * and updates the visibility if needed. - * @param {string} labelName The name of the label element that is being - * updated. - * @param {string} labelValue The new text content for the label. - * @param {boolean=} needsToBeShown True if we want to show the label - * False otherwise. - */ - setLabelAndShow_(labelName, labelValue, needsToBeShown = true) { - const labelElement = this.querySelector(labelName); - labelElement.textContent = labelValue ? ' ' + labelValue : ''; - if (needsToBeShown) { - labelElement.parentElement.hidden = false; - } - }, - /** - * Populate the box with the given cloud policy status. - * @param {string} scope The policy scope, either "device", "machine", - * "user", or "updater". - * @param {Object} status Dictionary with information about the status. - */ - initialize(scope, status) { - const notSpecifiedString = loadTimeData.getString('notSpecified'); - if (scope === 'device') { - // For device policy, set the appropriate title and populate the topmost - // status item with the domain the device is enrolled into. - this.querySelector('.legend').textContent = - loadTimeData.getString('statusDevice'); - this.setLabelAndShow_( - '.enterprise-enrollment-domain', status.enterpriseEnrollmentDomain); - - // Populate the device naming information. - // Populate the asset identifier. - this.setLabelAndShow_( - '.asset-id', status.assetId || notSpecifiedString); - - // Populate the device location. - this.setLabelAndShow_( - '.location', status.location || notSpecifiedString); - - // Populate the directory API ID. - this.setLabelAndShow_( - '.directory-api-id', status.directoryApiId || notSpecifiedString); - this.setLabelAndShow_('.client-id', status.clientId); - // For off-hours policy, indicate if it's active or not. - if (status.isOffHoursActive != null) { - this.setLabelAndShow_( - '.is-offhours-active', - loadTimeData.getString( - status.isOffHoursActive ? 'offHoursActive' : - 'offHoursNotActive')); - } - } else if (scope === 'machine') { - // For machine policy, set the appropriate title and populate - // machine enrollment status with the information that applies - // to this machine. - this.querySelector('.legend').textContent = - loadTimeData.getString('statusMachine'); - this.setLabelAndShow_('.machine-enrollment-device-id', status.deviceId); - this.setLabelAndShow_( - '.machine-enrollment-token', status.enrollmentToken); - this.setLabelAndShow_('.machine-enrollment-name', status.machine); - this.setLabelAndShow_('.machine-enrollment-domain', status.domain); - } else if (scope === 'updater') { - this.querySelector('.legend').textContent = - loadTimeData.getString('statusUpdater'); - if (status.version) { - this.setLabelAndShow_('.version', status.version); - } - if (status.domain) { - this.setLabelAndShow_('.enterprise-enrollment-domain', status.domain); - } - } else { - // For user policy, set the appropriate title and populate the topmost - // status item with the username that policies apply to. - this.querySelector('.legend').textContent = - loadTimeData.getString('statusUser'); - // Populate the topmost item with the username. - this.setLabelAndShow_('.username', status.username); - // Populate the user gaia id. - this.setLabelAndShow_('.gaia-id', status.gaiaId || notSpecifiedString); - this.setLabelAndShow_('.client-id', status.clientId); - if (status.isAffiliated != null) { - this.setLabelAndShow_( - '.is-affiliated', - loadTimeData.getString( - status.isAffiliated ? 'isAffiliatedYes' : 'isAffiliatedNo')); - } - } - - if (status.enterpriseDomainManager) { - this.setLabelAndShow_('.managed-by', status.enterpriseDomainManager); - } - - if (status.timeSinceLastRefresh) { - this.setLabelAndShow_( - '.time-since-last-refresh', status.timeSinceLastRefresh); - } - - if (scope !== 'updater') { - this.setLabelAndShow_('.refresh-interval', status.refreshInterval); - this.setLabelAndShow_('.status', status.status); - this.setLabelAndShow_( - '.policy-push', - loadTimeData.getString( - status.policiesPushAvailable ? 'policiesPushOn' : - 'policiesPushOff')); - } - }, - }; - - /** - * A single policy conflict's entry in the policy table. - * @constructor - * @extends {HTMLDivElement} - */ - const PolicyConflict = cr.ui.define(function() { - const node = $('policy-conflict-template').cloneNode(true); - node.removeAttribute('id'); - return node; - }); - - PolicyConflict.prototype = { - // Set up the prototype chain. - __proto__: HTMLDivElement.prototype, - - decorate() {}, - - /** - * @param {Conflict} conflict - * @param {string} row_label - */ - initialize(conflict, row_label) { - this.querySelector('.scope').textContent = loadTimeData.getString( - conflict.scope === 'user' ? 'scopeUser' : 'scopeDevice'); - this.querySelector('.level').textContent = loadTimeData.getString( - conflict.level === 'recommended' ? 'levelRecommended' : - 'levelMandatory'); - this.querySelector('.source').textContent = - loadTimeData.getString(conflict.source); - this.querySelector('.value.row .value').textContent = conflict.value; - this.querySelector('.name').textContent = - loadTimeData.getString(row_label); + setLabelAndShow_(labelName, labelValue, needsToBeShown = true) { + const labelElement = this.querySelector(labelName); + labelElement.textContent = labelValue ? ' ' + labelValue : ''; + if (needsToBeShown) { + labelElement.parentElement.hidden = false; } - }; + }, + /** + * Populate the box with the given cloud policy status. + * @param {string} scope The policy scope, either "device", "machine", + * "user", or "updater". + * @param {Object} status Dictionary with information about the status. + */ + initialize(scope, status) { + const notSpecifiedString = loadTimeData.getString('notSpecified'); + if (scope === 'device') { + // For device policy, set the appropriate title and populate the topmost + // status item with the domain the device is enrolled into. + this.querySelector('.legend').textContent = + loadTimeData.getString('statusDevice'); + this.setLabelAndShow_( + '.enterprise-enrollment-domain', status.enterpriseEnrollmentDomain); + + // Populate the device naming information. + // Populate the asset identifier. + this.setLabelAndShow_('.asset-id', status.assetId || notSpecifiedString); + + // Populate the device location. + this.setLabelAndShow_('.location', status.location || notSpecifiedString); + + // Populate the directory API ID. + this.setLabelAndShow_( + '.directory-api-id', status.directoryApiId || notSpecifiedString); + this.setLabelAndShow_('.client-id', status.clientId); + // For off-hours policy, indicate if it's active or not. + if (status.isOffHoursActive != null) { + this.setLabelAndShow_( + '.is-offhours-active', + loadTimeData.getString( + status.isOffHoursActive ? 'offHoursActive' : + 'offHoursNotActive')); + } + } else if (scope === 'machine') { + // For machine policy, set the appropriate title and populate + // machine enrollment status with the information that applies + // to this machine. + this.querySelector('.legend').textContent = + loadTimeData.getString('statusMachine'); + this.setLabelAndShow_('.machine-enrollment-device-id', status.deviceId); + this.setLabelAndShow_( + '.machine-enrollment-token', status.enrollmentToken); + this.setLabelAndShow_('.machine-enrollment-name', status.machine); + this.setLabelAndShow_('.machine-enrollment-domain', status.domain); + } else if (scope === 'updater') { + this.querySelector('.legend').textContent = + loadTimeData.getString('statusUpdater'); + if (status.version) { + this.setLabelAndShow_('.version', status.version); + } + if (status.domain) { + this.setLabelAndShow_('.enterprise-enrollment-domain', status.domain); + } + } else { + // For user policy, set the appropriate title and populate the topmost + // status item with the username that policies apply to. + this.querySelector('.legend').textContent = + loadTimeData.getString('statusUser'); + // Populate the topmost item with the username. + this.setLabelAndShow_('.username', status.username); + // Populate the user gaia id. + this.setLabelAndShow_('.gaia-id', status.gaiaId || notSpecifiedString); + this.setLabelAndShow_('.client-id', status.clientId); + if (status.isAffiliated != null) { + this.setLabelAndShow_( + '.is-affiliated', + loadTimeData.getString( + status.isAffiliated ? 'isAffiliatedYes' : 'isAffiliatedNo')); + } + } + + if (status.enterpriseDomainManager) { + this.setLabelAndShow_('.managed-by', status.enterpriseDomainManager); + } + + if (status.timeSinceLastRefresh) { + this.setLabelAndShow_( + '.time-since-last-refresh', status.timeSinceLastRefresh); + } + + if (scope !== 'updater') { + this.setLabelAndShow_('.refresh-interval', status.refreshInterval); + this.setLabelAndShow_('.status', status.status); + this.setLabelAndShow_( + '.policy-push', + loadTimeData.getString( + status.policiesPushAvailable ? 'policiesPushOn' : + 'policiesPushOff')); + } + }, +}; + +/** + * A single policy conflict's entry in the policy table. + * @constructor + * @extends {HTMLDivElement} + */ +const PolicyConflict = crUiDefine(function() { + const node = $('policy-conflict-template').cloneNode(true); + node.removeAttribute('id'); + return node; +}); + +PolicyConflict.prototype = { + // Set up the prototype chain. + __proto__: HTMLDivElement.prototype, + + decorate() {}, /** - * A single policy's row entry in the policy table. - * @constructor - * @extends {HTMLDivElement} + * @param {Conflict} conflict + * @param {string} row_label */ - const PolicyRow = cr.ui.define(function() { - const node = $('policy-template').cloneNode(true); - node.removeAttribute('id'); - return node; - }); + initialize(conflict, row_label) { + this.querySelector('.scope').textContent = loadTimeData.getString( + conflict.scope === 'user' ? 'scopeUser' : 'scopeDevice'); + this.querySelector('.level').textContent = loadTimeData.getString( + conflict.level === 'recommended' ? 'levelRecommended' : + 'levelMandatory'); + this.querySelector('.source').textContent = + loadTimeData.getString(conflict.source); + this.querySelector('.value.row .value').textContent = conflict.value; + this.querySelector('.name').textContent = loadTimeData.getString(row_label); + } +}; - PolicyRow.prototype = { - // Set up the prototype chain. - __proto__: HTMLDivElement.prototype, +/** + * A single policy's row entry in the policy table. + * @constructor + * @extends {HTMLDivElement} + */ +const PolicyRow = crUiDefine(function() { + const node = $('policy-template').cloneNode(true); + node.removeAttribute('id'); + return node; +}); - /** - * Initialization function for the cr.ui framework. - */ - decorate() { - const toggle = this.querySelector('.policy.row .toggle'); - toggle.addEventListener('click', this.toggleExpanded_.bind(this)); - - const copy = this.querySelector('.copy-value'); - copy.addEventListener('click', this.copyValue_.bind(this)); - }, - - /** @param {Policy} policy */ - initialize(policy) { - /** @type {Policy} */ - this.policy = policy; - - /** @private {boolean} */ - this.unset_ = policy.value === undefined; - - /** @private {boolean} */ - this.hasErrors_ = !!policy.error; - - /** @private {boolean} */ - this.hasWarnings_ = !!policy.warning; - - /** @private {boolean} */ - this.hasInfos_ = !!policy.info; - - /** @private {boolean} */ - this.hasConflicts_ = !!policy.conflicts; - - /** @private {boolean} */ - this.hasSuperseded_ = !!policy.superseded; - - /** @private {boolean} */ - this.isMergedValue_ = !!policy.allSourcesMerged; - - /** @private {boolean} */ - this.deprecated_ = !!policy.deprecated; - - /** @private {boolean} */ - this.future_ = !!policy.future; - - // Populate the name column. - const nameDisplay = this.querySelector('.name .link span'); - nameDisplay.textContent = policy.name; - if (policy.link) { - const link = this.querySelector('.name .link'); - link.href = policy.link; - link.title = loadTimeData.getStringF('policyLearnMore', policy.name); - } else { - this.classList.add('no-help-link'); - } - - // Populate the remaining columns with policy scope, level and value if a - // value has been set. Otherwise, leave them blank. - if (!this.unset_) { - const scopeDisplay = this.querySelector('.scope'); - scopeDisplay.textContent = loadTimeData.getString( - policy.scope === 'user' ? 'scopeUser' : 'scopeDevice'); - - const levelDisplay = this.querySelector('.level'); - levelDisplay.textContent = loadTimeData.getString( - policy.level === 'recommended' ? 'levelRecommended' : - 'levelMandatory'); - - const sourceDisplay = this.querySelector('.source'); - sourceDisplay.textContent = loadTimeData.getString(policy.source); - // Reduces load on the DOM for long values; - const truncatedValue = - (policy.value && policy.value.toString().length > 256) ? - `${policy.value.toString().substr(0, 256)}\u2026` : - policy.value; - - const valueDisplay = this.querySelector('.value'); - valueDisplay.textContent = truncatedValue; - - const copyLink = this.querySelector('.copy .link'); - copyLink.title = - loadTimeData.getStringF('policyCopyValue', policy.name); - - const valueRowContentDisplay = this.querySelector('.value.row .value'); - valueRowContentDisplay.textContent = policy.value; - - const errorRowContentDisplay = this.querySelector('.errors.row .value'); - errorRowContentDisplay.textContent = policy.error; - const warningRowContentDisplay = - this.querySelector('.warnings.row .value'); - warningRowContentDisplay.textContent = policy.warning; - const infoRowContentDisplay = this.querySelector('.infos.row .value'); - infoRowContentDisplay.textContent = policy.info; - - const messagesDisplay = this.querySelector('.messages'); - const errorsNotice = - this.hasErrors_ ? loadTimeData.getString('error') : ''; - const deprecationNotice = - this.deprecated_ ? loadTimeData.getString('deprecated') : ''; - const futureNotice = - this.future_ ? loadTimeData.getString('future') : ''; - const warningsNotice = - this.hasWarnings_ ? loadTimeData.getString('warning') : ''; - const conflictsNotice = this.hasConflicts_ && !this.isMergedValue_ ? - loadTimeData.getString('conflict') : - ''; - const ignoredNotice = - this.policy.ignored ? loadTimeData.getString('ignored') : ''; - let notice = - [ - errorsNotice, deprecationNotice, futureNotice, warningsNotice, - ignoredNotice, conflictsNotice - ].filter(x => !!x) - .join(', ') || - loadTimeData.getString('ok'); - const supersededNotice = this.hasSuperseded_ && !this.isMergedValue_ ? - loadTimeData.getString('superseding') : - ''; - if (supersededNotice) { - // Include superseded notice regardless of other notices - notice += `, ${supersededNotice}`; - } - messagesDisplay.textContent = notice; - - if (policy.conflicts) { - policy.conflicts.forEach(conflict => { - const row = new PolicyConflict; - row.initialize(conflict, 'conflictValue'); - this.appendChild(row); - }); - } - if (policy.superseded) { - policy.superseded.forEach(superseded => { - const row = new PolicyConflict; - row.initialize(superseded, 'supersededValue'); - this.appendChild(row); - }); - } - } else { - const messagesDisplay = this.querySelector('.messages'); - messagesDisplay.textContent = loadTimeData.getString('unset'); - } - }, - - /** - * Copies the policy's value to the clipboard. - * @private - */ - copyValue_() { - const policyValueDisplay = this.querySelector('.value.row .value'); - - // Select the text that will be copied. - const selection = window.getSelection(); - const range = window.document.createRange(); - range.selectNodeContents(policyValueDisplay); - selection.removeAllRanges(); - selection.addRange(range); - - // Copy the policy value to the clipboard. - navigator.clipboard.writeText(policyValueDisplay.innerText) - .catch(error => { - console.error('Unable to copy policy value to clipboard:', error); - }); - }, - - /** - * Toggle the visibility of an additional row containing the complete text. - * @private - */ - toggleExpanded_() { - const warningRowDisplay = this.querySelector('.warnings.row'); - const errorRowDisplay = this.querySelector('.errors.row'); - const infoRowDisplay = this.querySelector('.infos.row'); - const valueRowDisplay = this.querySelector('.value.row'); - valueRowDisplay.hidden = !valueRowDisplay.hidden; - if (valueRowDisplay.hidden) { - this.classList.remove('expanded'); - } else { - this.classList.add('expanded'); - } - - this.querySelector('.show-more').hidden = !valueRowDisplay.hidden; - this.querySelector('.show-less').hidden = valueRowDisplay.hidden; - if (this.hasWarnings_) { - warningRowDisplay.hidden = !warningRowDisplay.hidden; - } - if (this.hasErrors_) { - errorRowDisplay.hidden = !errorRowDisplay.hidden; - } - if (this.hasInfos_) { - infoRowDisplay.hidden = !infoRowDisplay.hidden; - } - this.querySelectorAll('.policy-conflict-data') - .forEach(row => row.hidden = !row.hidden); - this.querySelectorAll('.policy-superseded-data') - .forEach(row => row.hidden = !row.hidden); - }, - }; +PolicyRow.prototype = { + // Set up the prototype chain. + __proto__: HTMLDivElement.prototype, /** - * A table of policies and their values. - * @constructor - * @extends {HTMLDivElement} + * Initialization function for the cr.ui framework. */ - const PolicyTable = cr.ui.define(function() { - const node = $('policy-table-template').cloneNode(true); - node.removeAttribute('id'); - return node; - }); + decorate() { + const toggle = this.querySelector('.policy.row .toggle'); + toggle.addEventListener('click', this.toggleExpanded_.bind(this)); + + const copy = this.querySelector('.copy-value'); + copy.addEventListener('click', this.copyValue_.bind(this)); + }, + + /** @param {Policy} policy */ + initialize(policy) { + /** @type {Policy} */ + this.policy = policy; + + /** @private {boolean} */ + this.unset_ = policy.value === undefined; + + /** @private {boolean} */ + this.hasErrors_ = !!policy.error; + + /** @private {boolean} */ + this.hasWarnings_ = !!policy.warning; + + /** @private {boolean} */ + this.hasInfos_ = !!policy.info; + + /** @private {boolean} */ + this.hasConflicts_ = !!policy.conflicts; + + /** @private {boolean} */ + this.hasSuperseded_ = !!policy.superseded; + + /** @private {boolean} */ + this.isMergedValue_ = !!policy.allSourcesMerged; + + /** @private {boolean} */ + this.deprecated_ = !!policy.deprecated; + + /** @private {boolean} */ + this.future_ = !!policy.future; + + // Populate the name column. + const nameDisplay = this.querySelector('.name .link span'); + nameDisplay.textContent = policy.name; + if (policy.link) { + const link = this.querySelector('.name .link'); + link.href = policy.link; + link.title = loadTimeData.getStringF('policyLearnMore', policy.name); + } else { + this.classList.add('no-help-link'); + } + + // Populate the remaining columns with policy scope, level and value if a + // value has been set. Otherwise, leave them blank. + if (!this.unset_) { + const scopeDisplay = this.querySelector('.scope'); + scopeDisplay.textContent = loadTimeData.getString( + policy.scope === 'user' ? 'scopeUser' : 'scopeDevice'); + + const levelDisplay = this.querySelector('.level'); + levelDisplay.textContent = loadTimeData.getString( + policy.level === 'recommended' ? 'levelRecommended' : + 'levelMandatory'); + + const sourceDisplay = this.querySelector('.source'); + sourceDisplay.textContent = loadTimeData.getString(policy.source); + // Reduces load on the DOM for long values; + const truncatedValue = + (policy.value && policy.value.toString().length > 256) ? + `${policy.value.toString().substr(0, 256)}\u2026` : + policy.value; + + const valueDisplay = this.querySelector('.value'); + valueDisplay.textContent = truncatedValue; + + const copyLink = this.querySelector('.copy .link'); + copyLink.title = loadTimeData.getStringF('policyCopyValue', policy.name); + + const valueRowContentDisplay = this.querySelector('.value.row .value'); + valueRowContentDisplay.textContent = policy.value; + + const errorRowContentDisplay = this.querySelector('.errors.row .value'); + errorRowContentDisplay.textContent = policy.error; + const warningRowContentDisplay = + this.querySelector('.warnings.row .value'); + warningRowContentDisplay.textContent = policy.warning; + const infoRowContentDisplay = this.querySelector('.infos.row .value'); + infoRowContentDisplay.textContent = policy.info; + + const messagesDisplay = this.querySelector('.messages'); + const errorsNotice = + this.hasErrors_ ? loadTimeData.getString('error') : ''; + const deprecationNotice = + this.deprecated_ ? loadTimeData.getString('deprecated') : ''; + const futureNotice = this.future_ ? loadTimeData.getString('future') : ''; + const warningsNotice = + this.hasWarnings_ ? loadTimeData.getString('warning') : ''; + const conflictsNotice = this.hasConflicts_ && !this.isMergedValue_ ? + loadTimeData.getString('conflict') : + ''; + const ignoredNotice = + this.policy.ignored ? loadTimeData.getString('ignored') : ''; + let notice = + [ + errorsNotice, deprecationNotice, futureNotice, warningsNotice, + ignoredNotice, conflictsNotice + ].filter(x => !!x) + .join(', ') || + loadTimeData.getString('ok'); + const supersededNotice = this.hasSuperseded_ && !this.isMergedValue_ ? + loadTimeData.getString('superseding') : + ''; + if (supersededNotice) { + // Include superseded notice regardless of other notices + notice += `, ${supersededNotice}`; + } + messagesDisplay.textContent = notice; + + if (policy.conflicts) { + policy.conflicts.forEach(conflict => { + const row = new PolicyConflict; + row.initialize(conflict, 'conflictValue'); + this.appendChild(row); + }); + } + if (policy.superseded) { + policy.superseded.forEach(superseded => { + const row = new PolicyConflict; + row.initialize(superseded, 'supersededValue'); + this.appendChild(row); + }); + } + } else { + const messagesDisplay = this.querySelector('.messages'); + messagesDisplay.textContent = loadTimeData.getString('unset'); + } + }, + + /** + * Copies the policy's value to the clipboard. + * @private + */ + copyValue_() { + const policyValueDisplay = this.querySelector('.value.row .value'); + + // Select the text that will be copied. + const selection = window.getSelection(); + const range = window.document.createRange(); + range.selectNodeContents(policyValueDisplay); + selection.removeAllRanges(); + selection.addRange(range); + + // Copy the policy value to the clipboard. + navigator.clipboard.writeText(policyValueDisplay.innerText).catch(error => { + console.error('Unable to copy policy value to clipboard:', error); + }); + }, + + /** + * Toggle the visibility of an additional row containing the complete text. + * @private + */ + toggleExpanded_() { + const warningRowDisplay = this.querySelector('.warnings.row'); + const errorRowDisplay = this.querySelector('.errors.row'); + const infoRowDisplay = this.querySelector('.infos.row'); + const valueRowDisplay = this.querySelector('.value.row'); + valueRowDisplay.hidden = !valueRowDisplay.hidden; + if (valueRowDisplay.hidden) { + this.classList.remove('expanded'); + } else { + this.classList.add('expanded'); + } + + this.querySelector('.show-more').hidden = !valueRowDisplay.hidden; + this.querySelector('.show-less').hidden = valueRowDisplay.hidden; + if (this.hasWarnings_) { + warningRowDisplay.hidden = !warningRowDisplay.hidden; + } + if (this.hasErrors_) { + errorRowDisplay.hidden = !errorRowDisplay.hidden; + } + if (this.hasInfos_) { + infoRowDisplay.hidden = !infoRowDisplay.hidden; + } + this.querySelectorAll('.policy-conflict-data') + .forEach(row => row.hidden = !row.hidden); + this.querySelectorAll('.policy-superseded-data') + .forEach(row => row.hidden = !row.hidden); + }, +}; + +/** + * A table of policies and their values. + * @constructor + * @extends {HTMLDivElement} + */ +const PolicyTable = crUiDefine(function() { + const node = $('policy-table-template').cloneNode(true); + node.removeAttribute('id'); + return node; +}); - PolicyTable.prototype = { - // Set up the prototype chain. - __proto__: HTMLDivElement.prototype, +PolicyTable.prototype = { + // Set up the prototype chain. + __proto__: HTMLDivElement.prototype, - /** - * Initialization function for the cr.ui framework. - */ - decorate() { - this.policies_ = {}; - this.filterPattern_ = ''; - }, + /** + * Initialization function for the cr.ui framework. + */ + decorate() { + this.policies_ = {}; + this.filterPattern_ = ''; + }, - /** @param {PolicyTableModel} dataModel */ - update(dataModel) { - // Clear policies - const mainContent = this.querySelector('.main'); - const policies = this.querySelectorAll('.policy-data'); - this.querySelector('.header').textContent = dataModel.name; - this.querySelector('.id').textContent = dataModel.id; - this.querySelector('.id').hidden = !dataModel.id; - policies.forEach(row => mainContent.removeChild(row)); + /** @param {PolicyTableModel} dataModel */ + update(dataModel) { + // Clear policies + const mainContent = this.querySelector('.main'); + const policies = this.querySelectorAll('.policy-data'); + this.querySelector('.header').textContent = dataModel.name; + this.querySelector('.id').textContent = dataModel.id; + this.querySelector('.id').hidden = !dataModel.id; + policies.forEach(row => mainContent.removeChild(row)); - dataModel.policies - .sort((a, b) => { - if ((a.value !== undefined && b.value !== undefined) || - a.value === b.value) { - if (a.link !== undefined && b.link !== undefined) { - // Sorting the policies in ascending alpha order. - return a.name > b.name ? 1 : -1; - } - - // Sorting so unknown policies are last. - return a.link !== undefined ? -1 : 1; + dataModel.policies + .sort((a, b) => { + if ((a.value !== undefined && b.value !== undefined) || + a.value === b.value) { + if (a.link !== undefined && b.link !== undefined) { + // Sorting the policies in ascending alpha order. + return a.name > b.name ? 1 : -1; } - // Sorting so unset values are last. - return a.value !== undefined ? -1 : 1; - }) - .forEach(policy => { - const policyRow = new PolicyRow; - policyRow.initialize(policy); - mainContent.appendChild(policyRow); - }); - this.filter(); - }, + // Sorting so unknown policies are last. + return a.link !== undefined ? -1 : 1; + } - /** - * Set the filter pattern. Only policies whose name contains |pattern| are - * shown in the policy table. The filter is case insensitive. It can be - * disabled by setting |pattern| to an empty string. - * @param {string} pattern The filter pattern. - */ - setFilterPattern(pattern) { - this.filterPattern_ = pattern.toLowerCase(); - this.filter(); - }, - - /** - * Filter policies. Only policies whose name contains the filter pattern are - * shown in the table. Furthermore, policies whose value is not currently - * set are only shown if the corresponding checkbox is checked. - */ - filter() { - const showUnset = $('show-unset').checked; - const policies = this.querySelectorAll('.policy-data'); - for (let i = 0; i < policies.length; i++) { - const policyDisplay = policies[i]; - policyDisplay.hidden = - policyDisplay.policy.value === undefined && !showUnset || - policyDisplay.policy.name.toLowerCase().indexOf( - this.filterPattern_) === -1; - } - this.querySelector('.no-policy').hidden = - !!this.querySelector('.policy-data:not([hidden])'); - }, - }; + // Sorting so unset values are last. + return a.value !== undefined ? -1 : 1; + }) + .forEach(policy => { + const policyRow = new PolicyRow; + policyRow.initialize(policy); + mainContent.appendChild(policyRow); + }); + this.filter(); + }, /** - * A singleton object that handles communication between browser and WebUI. - * @constructor + * Set the filter pattern. Only policies whose name contains |pattern| are + * shown in the policy table. The filter is case insensitive. It can be + * disabled by setting |pattern| to an empty string. + * @param {string} pattern The filter pattern. */ - function Page() {} + setFilterPattern(pattern) { + this.filterPattern_ = pattern.toLowerCase(); + this.filter(); + }, - // Make Page a singleton. - cr.addSingletonGetter(Page); + /** + * Filter policies. Only policies whose name contains the filter pattern are + * shown in the table. Furthermore, policies whose value is not currently + * set are only shown if the corresponding checkbox is checked. + */ + filter() { + const showUnset = $('show-unset').checked; + const policies = this.querySelectorAll('.policy-data'); + for (let i = 0; i < policies.length; i++) { + const policyDisplay = policies[i]; + policyDisplay.hidden = + policyDisplay.policy.value === undefined && !showUnset || + policyDisplay.policy.name.toLowerCase().indexOf( + this.filterPattern_) === -1; + } + this.querySelector('.no-policy').hidden = + !!this.querySelector('.policy-data:not([hidden])'); + }, +}; - Page.prototype = { - /** - * Main initialization function. Called by the browser on page load. - */ - initialize() { - cr.ui.FocusOutlineManager.forDocument(document); +/** + * A singleton object that handles communication between browser and WebUI. + */ +export class Page { + constructor() { + /** @type {?Element} */ + this.mainSection = null; - this.mainSection = $('main-section'); + /** @type {{[id: string]: PolicyTable}} */ + this.policyTables = {}; + } - /** @type {{[id: string]: PolicyTable}} */ - this.policyTables = {}; + /** + * Main initialization function. Called by the browser on page load. + */ + initialize() { + FocusOutlineManager.forDocument(document); - // Place the initial focus on the filter input field. - $('filter').focus(); + this.mainSection = $('main-section'); - const self = this; - $('filter').onsearch = function(event) { - for (policyTable in self.policyTables) { - self.policyTables[policyTable].setFilterPattern(this.value); - } - }; - $('reload-policies').onclick = function(event) { - this.disabled = true; - $('screen-reader-message').textContent = - loadTimeData.getString('loadingPolicies'); - chrome.send('reloadPolicies'); - }; + // Place the initial focus on the filter input field. + $('filter').focus(); - $('export-policies').onclick = function(event) { - chrome.send('exportPoliciesJSON'); - }; - - $('copy-policies').onclick = function(event) { - chrome.send('copyPoliciesJSON'); - }; - - $('show-unset').onchange = function() { - for (policyTable in self.policyTables) { - self.policyTables[policyTable].filter(); - } - }; - - chrome.send('listenPoliciesUpdates'); - cr.addWebUIListener('status-updated', status => this.setStatus(status)); - cr.addWebUIListener( - 'policies-updated', - (names, values) => this.onPoliciesReceived_(names, values)); - }, - - /** - * @param {PolicyNamesResponse} policyNames - * @param {PolicyValuesResponse} policyValues - * @private - */ - onPoliciesReceived_(policyNames, policyValues) { - /** @type {Array<!PolicyTableModel>} */ - const policyGroups = policyValues.map(value => { - const knownPolicyNames = - policyNames[value.id] ? policyNames[value.id].policyNames : []; - const knownPolicyNamesSet = new Set(knownPolicyNames); - const receivedPolicyNames = Object.keys(value.policies); - const allPolicyNames = - Array.from(new Set([...knownPolicyNames, ...receivedPolicyNames])); - const policies = allPolicyNames.map( - name => Object.assign( - { - name, - link: knownPolicyNames === policyNames.chrome.policyNames && - knownPolicyNamesSet.has(name) ? - `https://cloud.google.com/docs/chrome-enterprise/policies/?policy=${ - name}` : - undefined, - }, - value.policies[name])); - - return { - name: value.forSigninScreen ? - `${value.name} [${loadTimeData.getString('signinProfile')}]` : - value.name, - id: value.isExtension ? value.id : null, - policies - }; - }); - - policyGroups.forEach(group => this.createOrUpdatePolicyTable(group)); - - this.reloadPoliciesDone(); - }, - - /** @param {PolicyTableModel} dataModel */ - createOrUpdatePolicyTable(dataModel) { - const id = `${dataModel.name}-${dataModel.id}`; - if (!this.policyTables[id]) { - this.policyTables[id] = new PolicyTable; - this.mainSection.appendChild(this.policyTables[id]); + $('filter').onsearch = () => { + for (const policyTable in this.policyTables) { + this.policyTables[policyTable].setFilterPattern($('filter').value); } - this.policyTables[id].update(dataModel); - }, - - /** - * Update the status section of the page to show the current cloud policy - * status. - * @param {Object} status Dictionary containing the current policy status. - */ - setStatus(status) { - // Remove any existing status boxes. - const container = $('status-box-container'); - while (container.firstChild) { - container.removeChild(container.firstChild); - } - // Hide the status section. - const section = $('status-section'); - section.hidden = true; - - // Add a status box for each scope that has a cloud policy status. - for (const scope in status) { - const box = new StatusBox; - box.initialize(scope, status[scope]); - container.appendChild(box); - // Show the status section. - section.hidden = false; - } - }, - - /** - * Re-enable the reload policies button when the previous request to reload - * policies values has completed. - */ - reloadPoliciesDone() { - $('reload-policies').disabled = false; + }; + $('reload-policies').onclick = () => { + $('reload-policies').disabled = true; $('screen-reader-message').textContent = - loadTimeData.getString('loadPoliciesDone'); - }, - }; + loadTimeData.getString('loadingPolicies'); + chrome.send('reloadPolicies'); + }; - return { - Page, - PolicyTable, - Policy, - PolicyNamesResponse, - PolicyValuesResponse, - Conflict, - PolicyRow, - PolicyTableModel - }; -}); + $('export-policies').onclick = () => { + chrome.send('exportPoliciesJSON'); + }; + + $('copy-policies').onclick = () => { + chrome.send('copyPoliciesJSON'); + }; + + $('show-unset').onchange = () => { + for (const policyTable in this.policyTables) { + this.policyTables[policyTable].filter(); + } + }; + + chrome.send('listenPoliciesUpdates'); + addWebUIListener('status-updated', status => this.setStatus(status)); + addWebUIListener( + 'policies-updated', + (names, values) => this.onPoliciesReceived_(names, values)); + } + + /** + * @param {PolicyNamesResponse} policyNames + * @param {PolicyValuesResponse} policyValues + * @private + */ + onPoliciesReceived_(policyNames, policyValues) { + /** @type {Array<!PolicyTableModel>} */ + const policyGroups = policyValues.map(value => { + const knownPolicyNames = + policyNames[value.id] ? policyNames[value.id].policyNames : []; + const knownPolicyNamesSet = new Set(knownPolicyNames); + const receivedPolicyNames = Object.keys(value.policies); + const allPolicyNames = + Array.from(new Set([...knownPolicyNames, ...receivedPolicyNames])); + const policies = allPolicyNames.map( + name => Object.assign( + { + name, + link: knownPolicyNames === policyNames.chrome.policyNames && + knownPolicyNamesSet.has(name) ? + `https://cloud.google.com/docs/chrome-enterprise/policies/?policy=${ + name}` : + undefined, + }, + value.policies[name])); + + return { + name: value.forSigninScreen ? + `${value.name} [${loadTimeData.getString('signinProfile')}]` : + value.name, + id: value.isExtension ? value.id : null, + policies + }; + }); + + policyGroups.forEach(group => this.createOrUpdatePolicyTable(group)); + + this.reloadPoliciesDone(); + } + + /** @param {PolicyTableModel} dataModel */ + createOrUpdatePolicyTable(dataModel) { + const id = `${dataModel.name}-${dataModel.id}`; + if (!this.policyTables[id]) { + this.policyTables[id] = new PolicyTable; + this.mainSection.appendChild(this.policyTables[id]); + } + this.policyTables[id].update(dataModel); + } + + /** + * Update the status section of the page to show the current cloud policy + * status. + * @param {Object} status Dictionary containing the current policy status. + */ + setStatus(status) { + // Remove any existing status boxes. + const container = $('status-box-container'); + while (container.firstChild) { + container.removeChild(container.firstChild); + } + // Hide the status section. + const section = $('status-section'); + section.hidden = true; + + // Add a status box for each scope that has a cloud policy status. + for (const scope in status) { + const box = new StatusBox; + box.initialize(scope, status[scope]); + container.appendChild(box); + // Show the status section. + section.hidden = false; + } + } + + /** + * Re-enable the reload policies button when the previous request to reload + * policies values has completed. + */ + reloadPoliciesDone() { + $('reload-policies').disabled = false; + $('screen-reader-message').textContent = + loadTimeData.getString('loadPoliciesDone'); + } +} + +// Make Page a singleton. +addSingletonGetter(Page);
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp index 2da5119..d487606 100644 --- a/components/policy_strings.grdp +++ b/components/policy_strings.grdp
@@ -277,6 +277,9 @@ <message name="IDS_POLICY_PROTO_PARSING_ERROR" desc="Text displayed when error is encountered during policy parsing/decoding."> Policy parsing error: <ph name="ERROR">$1<ex>Invalid JSON string: Line: 1, column: 14</ex></ph> </message> + <message name="IDS_POLICY_HEX_COLOR_ERROR" desc="Error message in the policy summary page for the BrowserThemeColor policy when the policy value is an invalid hex color."> + Value "<ph name="VALUE">$1<ex>#zzzzzz</ex></ph>" is an invalid hex color. + </message> <!-- chrome://policy --> <message name="IDS_POLICY_TITLE" desc="Page title and the title of the section that lists policies.">
diff --git a/components/policy_strings_grdp/IDS_POLICY_HEX_COLOR_ERROR.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_HEX_COLOR_ERROR.png.sha1 new file mode 100644 index 0000000..f9c3af3 --- /dev/null +++ b/components/policy_strings_grdp/IDS_POLICY_HEX_COLOR_ERROR.png.sha1
@@ -0,0 +1 @@ +0bfa86c15794d69a09cd25484c85be690770c86b \ No newline at end of file
diff --git a/components/query_tiles/internal/tile_config.cc b/components/query_tiles/internal/tile_config.cc index 590b3d3..93148417 100644 --- a/components/query_tiles/internal/tile_config.cc +++ b/components/query_tiles/internal/tile_config.cc
@@ -11,9 +11,6 @@ namespace query_tiles { -// Default base URL string for the Query Tiles server. -constexpr char kDefaultBaseURL[] = "https://chromeupboarding-pa.googleapis.com"; - // Default URL string for GetQueryTiles RPC. constexpr char kDefaultGetQueryTilePath[] = "/v1/querytiles"; @@ -119,15 +116,21 @@ } // namespace // static -GURL TileConfig::GetQueryTilesServerUrl() { - return GetQueryTilesServerUrl(base::GetFieldTrialParamValueByFeature( - features::kQueryTiles, kBaseURLKey)); -} +GURL TileConfig::GetQueryTilesServerUrl( + const std::string& base_url, + bool override_field_trial_param_value_if_empty) { + std::string url = base_url; + if (!override_field_trial_param_value_if_empty) { + std::string field_trial_server_url = base::GetFieldTrialParamValueByFeature( + features::kQueryTiles, kBaseURLKey); + if (!field_trial_server_url.empty()) + url = field_trial_server_url; + } -// static -GURL TileConfig::GetQueryTilesServerUrl(const std::string& base_url) { - GURL server_url = base_url.empty() ? GURL(kDefaultBaseURL) : GURL(base_url); - return BuildGetQueryTileURL(server_url, kDefaultGetQueryTilePath); + if (url.empty()) + return GURL(); + + return BuildGetQueryTileURL(GURL(url), kDefaultGetQueryTilePath); } // static
diff --git a/components/query_tiles/internal/tile_config.h b/components/query_tiles/internal/tile_config.h index d2401cc..71ffb94 100644 --- a/components/query_tiles/internal/tile_config.h +++ b/components/query_tiles/internal/tile_config.h
@@ -65,11 +65,14 @@ class TileConfig { public: - // Gets the URL for the Query Tiles server. - static GURL GetQueryTilesServerUrl(); - - // Gets the URL for the Query Tiles server, given the server address. - static GURL GetQueryTilesServerUrl(const std::string& base_url); + // Gets the URL for the Query Tiles service. If + // |override_field_trial_param_value_if_empty| is false, server URL provided + // by field trial param is preferred over |base_url|. Otherwise, |base_url| is + // used. This method could return an empty URL if no valid URL is provided + // though |base_url| or field trial param. + static GURL GetQueryTilesServerUrl( + const std::string& base_url, + bool override_field_trial_param_value_if_empty); // Gets whether running the background task requires unmeter network // condition.
diff --git a/components/query_tiles/internal/tile_config_unittest.cc b/components/query_tiles/internal/tile_config_unittest.cc index 47df101..7227419 100644 --- a/components/query_tiles/internal/tile_config_unittest.cc +++ b/components/query_tiles/internal/tile_config_unittest.cc
@@ -6,6 +6,7 @@ #include "base/test/scoped_feature_list.h" #include "components/query_tiles/switches.h" +#include "components/query_tiles/tile_service.h" #include "testing/gtest/include/gtest/gtest.h" namespace query_tiles { @@ -34,8 +35,10 @@ {kBackoffMaxDelayInMsKey, "567"}}; feature_list.InitAndEnableFeatureWithParameters(features::kQueryTiles, params); - EXPECT_EQ(TileConfig::GetQueryTilesServerUrl(), - "https://test.com/v1/querytiles"); + EXPECT_EQ(TileConfig::GetQueryTilesServerUrl("", false), + GURL("https://test.com/v1/querytiles")); + EXPECT_EQ(TileConfig::GetQueryTilesServerUrl("https://xyz.com", false), + GURL("https://test.com/v1/querytiles")); EXPECT_TRUE(TileConfig::GetIsUnMeteredNetworkRequired()); EXPECT_EQ(TileConfig::GetExperimentTag(), "1234"); EXPECT_EQ(TileConfig::GetExpireDuration(), base::TimeDelta::FromSeconds(100)); @@ -50,8 +53,9 @@ TEST(TileConfigTest, FinchConfigDefaultParameter) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(features::kQueryTiles); - EXPECT_EQ(TileConfig::GetQueryTilesServerUrl(), - "https://chromeupboarding-pa.googleapis.com/v1/querytiles"); + EXPECT_EQ(TileConfig::GetQueryTilesServerUrl("", true), GURL()); + EXPECT_EQ(TileConfig::GetQueryTilesServerUrl("https://xyz.com", true), + GURL("https://xyz.com/v1/querytiles")); EXPECT_FALSE(TileConfig::GetIsUnMeteredNetworkRequired()); EXPECT_TRUE(TileConfig::GetExperimentTag().empty()); EXPECT_EQ(TileConfig::GetExpireDuration(), base::TimeDelta::FromDays(2));
diff --git a/components/query_tiles/internal/tile_fetcher.cc b/components/query_tiles/internal/tile_fetcher.cc index 1194d1e7..8e1984a 100644 --- a/components/query_tiles/internal/tile_fetcher.cc +++ b/components/query_tiles/internal/tile_fetcher.cc
@@ -72,6 +72,8 @@ // TileFetcher implementation. void StartFetchForTiles(FinishedCallback callback) override { auto resource_request = BuildGetRequest(); + if (!resource_request) + return; url_loader_ = network::SimpleURLLoader::Create( std::move(resource_request), kQueryTilesFetcherTrafficAnnotation); url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( @@ -82,26 +84,29 @@ // Build the request to get tile info. std::unique_ptr<network::ResourceRequest> BuildGetRequest() { + if (url_.is_empty() && g_override_url_for_testing.Get().is_empty()) + return nullptr; auto request = std::make_unique<network::ResourceRequest>(); request->method = net::HttpRequestHeaders::kGetMethod; request->headers.SetHeader("x-goog-api-key", api_key_); request->headers.SetHeader("X-Client-Version", client_version_); request->headers.SetHeader(net::HttpRequestHeaders::kContentType, kRequestContentType); - request->url = - net::AppendOrReplaceQueryParameter(url_, "country_code", country_code_); - if (!experiment_tag_.empty()) { - request->url = net::AppendOrReplaceQueryParameter( - request->url, "experiment_tag", experiment_tag_); + if (!g_override_url_for_testing.Get().is_empty()) { + request->url = g_override_url_for_testing.Get(); + } else { + request->url = net::AppendOrReplaceQueryParameter(url_, "country_code", + country_code_); + if (!experiment_tag_.empty()) { + request->url = net::AppendOrReplaceQueryParameter( + request->url, "experiment_tag", experiment_tag_); + } } if (!accept_languages_.empty()) { request->headers.SetHeader(net::HttpRequestHeaders::kAcceptLanguage, accept_languages_); } - if (!g_override_url_for_testing.Get().is_empty()) - request->url = g_override_url_for_testing.Get(); - return request; }
diff --git a/components/query_tiles/internal/tile_service_impl.cc b/components/query_tiles/internal/tile_service_impl.cc index 2dbe42c..587d1b7 100644 --- a/components/query_tiles/internal/tile_service_impl.cc +++ b/components/query_tiles/internal/tile_service_impl.cc
@@ -80,7 +80,8 @@ void TileServiceImpl::SetServerUrl(const std::string& base_url) { if (base_url.empty()) return; - tile_fetcher_->SetServerUrl(TileConfig::GetQueryTilesServerUrl(base_url)); + tile_fetcher_->SetServerUrl( + TileConfig::GetQueryTilesServerUrl(base_url, true)); } void TileServiceImpl::OnFetchFinished(
diff --git a/components/query_tiles/tile_service_factory_helper.cc b/components/query_tiles/tile_service_factory_helper.cc index edfe069c..0af046c 100644 --- a/components/query_tiles/tile_service_factory_helper.cc +++ b/components/query_tiles/tile_service_factory_helper.cc
@@ -59,6 +59,7 @@ const std::string& country_code, const std::string& api_key, const std::string& client_version, + const std::string& default_server_url, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, PrefService* pref_service) { // Create image loader. @@ -87,9 +88,9 @@ // Create fetcher. auto tile_fetcher = TileFetcher::Create( - TileConfig::GetQueryTilesServerUrl(), country_code, accepted_language, - api_key, TileConfig::GetExperimentTag(), client_version, - url_loader_factory); + TileConfig::GetQueryTilesServerUrl(default_server_url, false), + country_code, accepted_language, api_key, TileConfig::GetExperimentTag(), + client_version, url_loader_factory); // Wrap background task scheduler. auto policy = std::make_unique<net::BackoffEntry::Policy>();
diff --git a/components/query_tiles/tile_service_factory_helper.h b/components/query_tiles/tile_service_factory_helper.h index 1202fe63..c871ca4a 100644 --- a/components/query_tiles/tile_service_factory_helper.h +++ b/components/query_tiles/tile_service_factory_helper.h
@@ -41,6 +41,7 @@ const std::string& country_code, const std::string& api_key, const std::string& client_version, + const std::string& default_server_url, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, PrefService* pref_service);
diff --git a/components/remote_cocoa/browser/scoped_cg_window_id.cc b/components/remote_cocoa/browser/scoped_cg_window_id.cc index a58f825..56f618e 100644 --- a/components/remote_cocoa/browser/scoped_cg_window_id.cc +++ b/components/remote_cocoa/browser/scoped_cg_window_id.cc
@@ -53,6 +53,14 @@ observer_list_.RemoveObserver(observer); } +void ScopedCGWindowID::OnMouseMoved(const gfx::PointF& location_in_window, + const gfx::Size& window_size) { + for (auto& observer : observer_list_) { + observer.OnScopedCGWindowIDMouseMoved(cg_window_id_, location_in_window, + window_size); + } +} + // static base::WeakPtr<ScopedCGWindowID> ScopedCGWindowID::Get(uint32_t cg_window_id) { auto found = GetMap().find(cg_window_id);
diff --git a/components/remote_cocoa/browser/scoped_cg_window_id.h b/components/remote_cocoa/browser/scoped_cg_window_id.h index 11d4375..883ad18 100644 --- a/components/remote_cocoa/browser/scoped_cg_window_id.h +++ b/components/remote_cocoa/browser/scoped_cg_window_id.h
@@ -12,6 +12,8 @@ #include "base/threading/thread_checker.h" #include "components/remote_cocoa/browser/remote_cocoa_browser_export.h" #include "components/viz/common/surfaces/frame_sink_id.h" +#include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/size.h" namespace remote_cocoa { @@ -26,6 +28,10 @@ // This is invoked in the ScopedCGWindowID destructor, after all of its // weak pointers have been destroyed. virtual void OnScopedCGWindowIDDestroyed(uint32_t cg_window_id) {} + virtual void OnScopedCGWindowIDMouseMoved( + uint32_t cg_window_id, + const gfx::PointF& location_in_window_dips, + const gfx::Size& window_size_dips) {} }; ScopedCGWindowID(uint32_t cg_window_id, const viz::FrameSinkId& frame_sink_id); @@ -38,6 +44,11 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + // Inform frame sink capturers of where the mouse is, so that they can draw + // a cursor. + void OnMouseMoved(const gfx::PointF& location_in_window_dips, + const gfx::Size& window_size_dips); + // Query the frame sink id for this window, which can be used for optimized // video capture. const viz::FrameSinkId& GetFrameSinkId() const { return frame_sink_id_; }
diff --git a/components/reporting/storage/storage.cc b/components/reporting/storage/storage.cc index b1b9f5c..83640c76 100644 --- a/components/reporting/storage/storage.cc +++ b/components/reporting/storage/storage.cc
@@ -119,16 +119,16 @@ : priority_(priority), storage_interface_(std::move(storage_interface)) {} // Factory method. - static StatusOr<std::unique_ptr<UploaderInterface>> ProvideUploader( + static void AsyncProvideUploader( Priority priority, - Storage* storage) { - ASSIGN_OR_RETURN( - std::unique_ptr<UploaderInterface> uploader, - storage->start_upload_cb_.Run( - priority, EncryptionModuleInterface::is_enabled() && - storage->encryption_module_->need_encryption_key())); - return std::make_unique<QueueUploaderInterface>(priority, - std::move(uploader)); + Storage* storage, + UploaderInterface::UploaderInterfaceResultCb start_uploader_cb) { + storage->async_start_upload_cb_.Run( + priority, + /*need_encryption_key=*/EncryptionModuleInterface::is_enabled() && + storage->encryption_module_->need_encryption_key(), + base::BindOnce(&QueueUploaderInterface::WrapInstantiatedUploader, + priority, std::move(start_uploader_cb))); } void ProcessRecord(EncryptedRecord encrypted_record, @@ -155,6 +155,19 @@ } private: + static void WrapInstantiatedUploader( + Priority priority, + UploaderInterface::UploaderInterfaceResultCb start_uploader_cb, + StatusOr<std::unique_ptr<UploaderInterface>> uploader_result) { + if (!uploader_result.ok()) { + std::move(start_uploader_cb).Run(uploader_result.status()); + return; + } + std::move(start_uploader_cb) + .Run(std::make_unique<QueueUploaderInterface>( + priority, std::move(uploader_result.ValueOrDie()))); + } + const Priority priority_; const std::unique_ptr<UploaderInterface> storage_interface_; }; @@ -430,7 +443,7 @@ void Storage::Create( const StorageOptions& options, - UploaderInterface::StartCb start_upload_cb, + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb, scoped_refptr<EncryptionModuleInterface> encryption_module, base::OnceCallback<void(StatusOr<scoped_refptr<Storage>>)> completion_cb) { // Initialize Storage object, populating all the queues. @@ -486,17 +499,12 @@ DCHECK(storage_->encryption_module_->has_encryption_key()); } else { if (EncryptionModuleInterface::is_enabled()) { - // Encryptor enabled - we cannot proceed with no keys. - // Send Upload with need_encryption_key flag and no records. - StatusOr<std::unique_ptr<UploaderInterface>> uploader = - storage_->start_upload_cb_.Run( - /*priority=*/MANUAL_BATCH, // Any priority would do. - /*need_encryption_key=*/true); - if (!uploader.ok()) { - Response(uploader.status()); - return; - } - uploader.ValueOrDie()->Completed(Status::StatusOK()); + // Initiate upload with need_encryption_key flag and no records. + storage_->async_start_upload_cb_.Run( + /*priority=*/MANUAL_BATCH, // Any priority would do. + /*need_encryption_key=*/true, + base::BindOnce(&StorageInitContext::EncryptionKeyReceiverReady, + base::Unretained(this))); // Continue initialization without waiting for it to respond. // Until the response arrives, we will reject Enqueues. } @@ -509,7 +517,7 @@ /*options=*/queue_options.second, // Note: the callback below belongs to the Queue and does not // outlive Storage. - base::BindRepeating(&QueueUploaderInterface::ProvideUploader, + base::BindRepeating(&QueueUploaderInterface::AsyncProvideUploader, /*priority=*/queue_options.first, base::Unretained(storage_.get())), storage_->encryption_module_, @@ -519,6 +527,13 @@ } } + void EncryptionKeyReceiverReady( + StatusOr<std::unique_ptr<UploaderInterface>> uploader_result) { + if (uploader_result.ok()) { + uploader_result.ValueOrDie()->Completed(Status::StatusOK()); + } + } + void ScheduleAddQueue( Priority priority, StatusOr<scoped_refptr<StorageQueue>> storage_queue_result) { @@ -559,8 +574,8 @@ // Create Storage object. // Cannot use base::MakeRefCounted<Storage>, because constructor is private. - scoped_refptr<Storage> storage = base::WrapRefCounted( - new Storage(options, encryption_module, std::move(start_upload_cb))); + scoped_refptr<Storage> storage = base::WrapRefCounted(new Storage( + options, encryption_module, std::move(async_start_upload_cb))); // Asynchronously run initialization. Start<StorageInitContext>(ExpectedQueues(storage->options_), @@ -569,13 +584,13 @@ Storage::Storage(const StorageOptions& options, scoped_refptr<EncryptionModuleInterface> encryption_module, - UploaderInterface::StartCb start_upload_cb) + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb) : options_(options), encryption_module_(encryption_module), key_in_storage_(std::make_unique<KeyInStorage>( options.signature_verification_public_key(), options.directory())), - start_upload_cb_(std::move(start_upload_cb)) {} + async_start_upload_cb_(std::move(async_start_upload_cb)) {} Storage::~Storage() = default;
diff --git a/components/reporting/storage/storage.h b/components/reporting/storage/storage.h index 6c9d697..cf0bffcd 100644 --- a/components/reporting/storage/storage.h +++ b/components/reporting/storage/storage.h
@@ -34,7 +34,7 @@ // Creates Storage instance, and returns it with the completion callback. static void Create( const StorageOptions& options, - UploaderInterface::StartCb start_upload_cb, + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb, scoped_refptr<EncryptionModuleInterface> encryption_module, base::OnceCallback<void(StatusOr<scoped_refptr<Storage>>)> completion_cb); @@ -86,7 +86,7 @@ // Queues need to be added afterwards. Storage(const StorageOptions& options, scoped_refptr<EncryptionModuleInterface> encryption_module, - UploaderInterface::StartCb start_upload_cb); + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb); // Initializes the object by adding all queues for all priorities. // Must be called once and only once after construction. @@ -112,7 +112,7 @@ base::flat_map<Priority, scoped_refptr<StorageQueue>> queues_; // Upload provider callback. - const UploaderInterface::StartCb start_upload_cb_; + const UploaderInterface::AsyncStartUploaderCb async_start_upload_cb_; }; } // namespace reporting
diff --git a/components/reporting/storage/storage_module.cc b/components/reporting/storage/storage_module.cc index b3fadd4b..43b963f6 100644 --- a/components/reporting/storage/storage_module.cc +++ b/components/reporting/storage/storage_module.cc
@@ -57,7 +57,7 @@ // static void StorageModule::Create( const StorageOptions& options, - UploaderInterface::StartCb start_upload_cb, + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb, scoped_refptr<EncryptionModuleInterface> encryption_module, base::OnceCallback<void(StatusOr<scoped_refptr<StorageModuleInterface>>)> callback) { @@ -65,7 +65,7 @@ // Cannot base::MakeRefCounted, since constructor is protected. base::WrapRefCounted(new StorageModule()); Storage::Create( - options, start_upload_cb, encryption_module, + options, async_start_upload_cb, encryption_module, base::BindOnce( [](scoped_refptr<StorageModule> instance, base::OnceCallback<void(
diff --git a/components/reporting/storage/storage_module.h b/components/reporting/storage/storage_module.h index ba67268b..31c5a21 100644 --- a/components/reporting/storage/storage_module.h +++ b/components/reporting/storage/storage_module.h
@@ -27,7 +27,7 @@ // Factory method creates |StorageModule| object. static void Create( const StorageOptions& options, - UploaderInterface::StartCb start_upload_cb, + UploaderInterface::AsyncStartUploaderCb async_start_upload_cb, scoped_refptr<EncryptionModuleInterface> encryption_module, base::OnceCallback<void(StatusOr<scoped_refptr<StorageModuleInterface>>)> callback);
diff --git a/components/reporting/storage/storage_queue.cc b/components/reporting/storage/storage_queue.cc index e872a07..27f857e 100644 --- a/components/reporting/storage/storage_queue.cc +++ b/components/reporting/storage/storage_queue.cc
@@ -76,7 +76,7 @@ // static void StorageQueue::Create( const QueueOptions& options, - StartUploadCb start_upload_cb, + AsyncStartUploaderCb async_start_upload_cb, scoped_refptr<EncryptionModuleInterface> encryption_module, base::OnceCallback<void(StatusOr<scoped_refptr<StorageQueue>>)> completion_cb) { @@ -114,8 +114,9 @@ // Create StorageQueue object. // Cannot use base::MakeRefCounted<StorageQueue>, because constructor is // private. - scoped_refptr<StorageQueue> storage_queue = base::WrapRefCounted( - new StorageQueue(options, std::move(start_upload_cb), encryption_module)); + scoped_refptr<StorageQueue> storage_queue = + base::WrapRefCounted(new StorageQueue( + options, std::move(async_start_upload_cb), encryption_module)); // Asynchronously run initialization. Start<StorageQueueInitContext>(std::move(storage_queue), @@ -124,10 +125,10 @@ StorageQueue::StorageQueue( const QueueOptions& options, - StartUploadCb start_upload_cb, + AsyncStartUploaderCb async_start_upload_cb, scoped_refptr<EncryptionModuleInterface> encryption_module) : options_(options), - start_upload_cb_(std::move(start_upload_cb)), + async_start_upload_cb_(async_start_upload_cb), encryption_module_(encryption_module), sequenced_task_runner_(base::ThreadPool::CreateSequencedTaskRunner( {base::TaskPriority::BEST_EFFORT, base::MayBlock()})) { @@ -666,16 +667,15 @@ // is zero, RemoveConfirmedData can delete the unused files). class StorageQueue::ReadContext : public TaskRunnerContext<Status> { public: - ReadContext(std::unique_ptr<UploaderInterface> uploader, - scoped_refptr<StorageQueue> storage_queue) + explicit ReadContext(scoped_refptr<StorageQueue> storage_queue) : TaskRunnerContext<Status>( - base::BindOnce(&UploaderInterface::Completed, - base::Unretained(uploader.get())), + base::BindOnce(&ReadContext::UploadingCompleted, + base::Unretained(this)), storage_queue->sequenced_task_runner_), - uploader_(std::move(uploader)), + async_start_upload_cb_(storage_queue->async_start_upload_cb_), storage_queue_weakptr_factory_{storage_queue.get()} { DCHECK(storage_queue.get()); - DCHECK(uploader_.get()); + DCHECK(async_start_upload_cb_); DETACH_FROM_SEQUENCE(read_sequence_checker_); } @@ -691,6 +691,42 @@ Response(Status(error::UNAVAILABLE, "StorageQueue shut down")); return; } + base::ThreadPool::PostTask( + FROM_HERE, {base::TaskPriority::BEST_EFFORT}, + base::BindOnce( + [](ReadContext* self) { + self->async_start_upload_cb_.Run( + base::BindOnce(&ReadContext::ScheduleOnUploaderInstantiated, + base::Unretained(self))); + }, + base::Unretained(this))); + } + + void ScheduleOnUploaderInstantiated( + StatusOr<std::unique_ptr<UploaderInterface>> uploader_result) { + Schedule(base::BindOnce(&ReadContext::OnUploaderInstantiated, + base::Unretained(this), + std::move(uploader_result))); + } + + void OnUploaderInstantiated( + StatusOr<std::unique_ptr<UploaderInterface>> uploader_result) { + DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_); + base::WeakPtr<StorageQueue> storage_queue = + storage_queue_weakptr_factory_.GetWeakPtr(); + if (!storage_queue) { + Response(Status(error::UNAVAILABLE, "StorageQueue shut down")); + return; + } + if (!uploader_result.ok()) { + Response(Status(error::FAILED_PRECONDITION, + base::StrCat({"Failed to provide the Uploader, status=", + uploader_result.status().ToString()}))); + return; + } + DCHECK(!uploader_) + << "Uploader instantiated more than once for single upload"; + uploader_ = std::move(uploader_result.ValueOrDie()); // Fill in initial sequencing information to track progress: // use minimum of first_sequencing_id_ and first_unconfirmed_sequencing_id_ @@ -779,6 +815,13 @@ // Resume at ScheduleNextRecord. } + void UploadingCompleted(Status status) { + // If uploader was created, notify it about completion. + if (uploader_) { + uploader_->Completed(status); + } + } + void OnCompletion() override { DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_); // Unregister with storage_queue. @@ -1002,7 +1045,8 @@ SequencingInformation sequencing_info_; uint32_t current_pos_; std::map<int64_t, scoped_refptr<SingleFile>>::iterator current_file_; - const std::unique_ptr<UploaderInterface> uploader_; + const AsyncStartUploaderCb async_start_upload_cb_; + std::unique_ptr<UploaderInterface> uploader_; base::WeakPtrFactory<StorageQueue> storage_queue_weakptr_factory_; SEQUENCE_CHECKER(read_sequence_checker_); @@ -1043,14 +1087,14 @@ } // If no uploader is needed, we are done. - if (!uploader_) { + if (!async_start_upload_cb_) { return; } // Otherwise initiate Upload right after writing // finished and respond back when reading Upload is done. // Note: new uploader created synchronously before scheduling Upload. - Start<ReadContext>(std::move(uploader_), storage_queue_); + Start<ReadContext>(storage_queue_); } void OnStart() override { @@ -1168,14 +1212,7 @@ // Prepare uploader, if need to run it after Write. if (storage_queue_->options_.upload_period().is_zero()) { - StatusOr<std::unique_ptr<UploaderInterface>> uploader = - storage_queue_->start_upload_cb_.Run(); - if (uploader.ok()) { - uploader_ = std::move(uploader.ValueOrDie()); - } else { - LOG(ERROR) << "Failed to provide the Uploader, status=" - << uploader.status(); - } + async_start_upload_cb_ = storage_queue_->async_start_upload_cb_; } DCHECK(!buffer_.empty()); @@ -1218,8 +1255,8 @@ // executed. Empty until encryption is done. std::string buffer_; - // Upload provider (if any). - std::unique_ptr<UploaderInterface> uploader_; + // Upload provider. + AsyncStartUploaderCb async_start_upload_cb_; SEQUENCE_CHECKER(write_sequence_checker_); }; @@ -1359,14 +1396,7 @@ void StorageQueue::Flush() { // Note: new uploader created every time Flush is called. - StatusOr<std::unique_ptr<UploaderInterface>> uploader = - start_upload_cb_.Run(); - if (!uploader.ok()) { - LOG(ERROR) << "Failed to provide the Uploader, status=" - << uploader.status(); - return; - } - Start<ReadContext>(std::move(uploader.ValueOrDie()), this); + Start<ReadContext>(this); } void StorageQueue::ReleaseAllFileInstances() {
diff --git a/components/reporting/storage/storage_queue.h b/components/reporting/storage/storage_queue.h index e5b58888..c8ac090 100644 --- a/components/reporting/storage/storage_queue.h +++ b/components/reporting/storage/storage_queue.h
@@ -40,17 +40,17 @@ class StorageQueue : public base::RefCountedThreadSafe<StorageQueue> { public: // Callback type for UploadInterface provider for this queue. - using StartUploadCb = - base::RepeatingCallback<StatusOr<std::unique_ptr<UploaderInterface>>()>; + using AsyncStartUploaderCb = base::RepeatingCallback<void( + UploaderInterface::UploaderInterfaceResultCb)>; // Creates StorageQueue instance with the specified options, and returns it - // with the |completion_cb| callback. |start_upload_cb| is a factory callback - // that instantiates UploaderInterface every time the queue starts uploading - // records - periodically or immediately after Write (and in the near future - - // upon explicit Flush request). + // with the |completion_cb| callback. |async_start_upload_cb| is a factory + // callback that instantiates UploaderInterface every time the queue starts + // uploading records - periodically or immediately after Write (and in the + // near future - upon explicit Flush request). static void Create( const QueueOptions& options, - StartUploadCb start_upload_cb, + AsyncStartUploaderCb async_start_upload_cb, scoped_refptr<EncryptionModuleInterface> encryption_module, base::OnceCallback<void(StatusOr<scoped_refptr<StorageQueue>>)> completion_cb); @@ -80,22 +80,23 @@ // on upload_period of the queue, and can also be called explicitly - for // a queue with an infinite or very large upload period. Multiple |Flush| // calls can safely run in parallel. - // Starts by calling |start_upload_cb_| that instantiates |UploaderInterface - // uploader|. Then repeatedly reads EncryptedRecord(s) one by one from the - // StorageQueue starting from |first_sequencing_id_|, handing each one over to - // |uploader|->ProcessRecord (keeping ownership of the buffer) and resuming - // after result callback returns 'true'. Only files that have been closed are - // included in reading; |Upload| makes sure to close the last writeable file - // and create a new one before starting to send records to the |uploader|. - // If some records are not available or corrupt, |uploader|->ProcessGap is - // called. If the monotonic order of sequencing is broken, INTERNAL error - // Status is reported. |Upload| can be stopped after any record by returning - // 'false' to |processed_cb| callback - in that case |Upload| will behave as - // if the end of data has been reached. While one or more |Upload|s are - // active, files can be added to the StorageQueue but cannot be deleted. If - // processing of the record takes significant time, |uploader| implementation - // should be offset to another thread to avoid locking StorageQueue. - // Helper methods: SwitchLastFileIfNotEmpty, CollectFilesForUpload. + // Starts by calling |async_start_upload_cb_| that instantiates + // |UploaderInterface uploader|. Then repeatedly reads EncryptedRecord(s) one + // by one from the StorageQueue starting from |first_sequencing_id_|, handing + // each one over to |uploader|->ProcessRecord (keeping ownership of the + // buffer) and resuming after result callback returns 'true'. Only files that + // have been closed are included in reading; |Upload| makes sure to close the + // last writeable file and create a new one before starting to send records to + // the |uploader|. If some records are not available or corrupt, + // |uploader|->ProcessGap is called. If the monotonic order of sequencing is + // broken, INTERNAL error Status is reported. |Upload| can be stopped after + // any record by returning 'false' to |processed_cb| callback - in that case + // |Upload| will behave as if the end of data has been reached. While one or + // more |Upload|s are active, files can be added to the StorageQueue but + // cannot be deleted. If processing of the record takes significant time, + // |uploader| implementation should be offset to another thread to avoid + // locking StorageQueue. Helper methods: SwitchLastFileIfNotEmpty, + // CollectFilesForUpload. void Flush(); // Test only: makes specified records fail on reading. @@ -187,7 +188,7 @@ // Private constructor, to be called by Create factory method only. StorageQueue(const QueueOptions& options, - StartUploadCb start_upload_cb, + AsyncStartUploaderCb async_start_upload_cb, scoped_refptr<EncryptionModuleInterface> encryption_module); // Initializes the object by enumerating files in the assigned directory @@ -329,7 +330,7 @@ base::RepeatingTimer upload_timer_; // Upload provider callback. - const StartUploadCb start_upload_cb_; + const AsyncStartUploaderCb async_start_upload_cb_; // Encryption module. scoped_refptr<EncryptionModuleInterface> encryption_module_;
diff --git a/components/reporting/storage/storage_queue_stress_test.cc b/components/reporting/storage/storage_queue_stress_test.cc index d7797bb..cc5531a 100644 --- a/components/reporting/storage/storage_queue_stress_test.cc +++ b/components/reporting/storage/storage_queue_stress_test.cc
@@ -154,7 +154,7 @@ storage_queue_create_event; StorageQueue::Create( options, - base::BindRepeating(&StorageQueueStressTest::BuildTestUploader, + base::BindRepeating(&StorageQueueStressTest::AsyncStartTestUploader, base::Unretained(this)), test_encryption_module_, storage_queue_create_event.cb()); StatusOr<scoped_refptr<StorageQueue>> storage_queue_result = @@ -184,8 +184,10 @@ return BuildStorageQueueOptionsPeriodic(base::TimeDelta::Max()); } - StatusOr<std::unique_ptr<UploaderInterface>> BuildTestUploader() { - return std::make_unique<TestUploadClient>(&last_record_digest_map_); + void AsyncStartTestUploader( + UploaderInterface::UploaderInterfaceResultCb start_uploader_cb) { + std::move(start_uploader_cb) + .Run(std::make_unique<TestUploadClient>(&last_record_digest_map_)); } void WriteStringAsync(base::StringPiece data,
diff --git a/components/reporting/storage/storage_queue_unittest.cc b/components/reporting/storage/storage_queue_unittest.cc index cf25e4b..8fc556e 100644 --- a/components/reporting/storage/storage_queue_unittest.cc +++ b/components/reporting/storage/storage_queue_unittest.cc
@@ -283,7 +283,7 @@ storage_queue_create_event; StorageQueue::Create( options, - base::BindRepeating(&StorageQueueTest::BuildMockUploader, + base::BindRepeating(&StorageQueueTest::AsyncStartMockUploader, base::Unretained(this)), test_encryption_module_, storage_queue_create_event.cb()); StatusOr<scoped_refptr<StorageQueue>> storage_queue_result = @@ -317,11 +317,12 @@ return BuildStorageQueueOptionsPeriodic(base::TimeDelta::Max()); } - StatusOr<std::unique_ptr<UploaderInterface>> BuildMockUploader() { + void AsyncStartMockUploader( + UploaderInterface::UploaderInterfaceResultCb start_uploader_cb) { auto uploader = std::make_unique<MockUploadClient>(&last_record_digest_map_); set_mock_uploader_expectations_.Call(uploader.get()); - return uploader; + std::move(start_uploader_cb).Run(std::move(uploader)); } Status WriteString(base::StringPiece data) { @@ -630,7 +631,7 @@ // Set uploader expectations. EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) - .WillOnce(Invoke([&data](MockUploadClient* mock_upload_client) { + .WillOnce(Invoke([data](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp client_setup(mock_upload_client); for (size_t i = 0; i < data.size(); ++i) { client_setup.Required(i, data[i]); @@ -885,23 +886,21 @@ .Required(0, kData[0]) .Possible(1, kData[1]) .Possible(2, kData[2]); - })); - WriteStringOrDie(kData[0]); - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .Required(0, kData[0]) .Required(1, kData[1]) .Possible(2, kData[2]); - })); - WriteStringOrDie(kData[1]); - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .Required(0, kData[0]) .Required(1, kData[1]) .Required(2, kData[2]); })); + WriteStringOrDie(kData[0]); + WriteStringOrDie(kData[1]); WriteStringOrDie(kData[2]); } @@ -918,51 +917,37 @@ .Possible(0, kData[0]) .Possible(1, kData[1]) .Possible(2, kData[2]); - })); - WriteStringOrDie(kData[0]); - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .Possible(0, kData[0]) .Possible(1, kData[1]) .Possible(2, kData[2]); - })); - WriteStringOrDie(kData[1]); - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .Possible(0, kData[0]) .Possible(1, kData[1]) .Required(2, kData[2]); // Not confirmed - hence |Required| - })); - WriteStringOrDie(kData[2]); - - // Confirm #1, removing data #0 and #1 - ConfirmOrDie(/*sequencing_id=*/1); - - // Add more data and verify that #2 and new data are returned. - // Upload is initiated asynchronously, so it may happen after the next - // record is also written. Because of that we set expectations for the - // data after the current one as |Possible|. - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) + // After adding more data verify that #2 and new data are returned. + // Upload is initiated asynchronously, so it may happen after the next + // record is also written. Because of that we set expectations for the + // data after the current one as |Possible|. .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .Required(2, kData[2]) .Required(3, kMoreData[0]) .Possible(4, kMoreData[1]) .Possible(5, kMoreData[2]); - })); - WriteStringOrDie(kMoreData[0]); - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .Required(2, kData[2]) .Required(3, kMoreData[0]) .Required(4, kMoreData[1]) .Possible(5, kMoreData[2]); - })); - WriteStringOrDie(kMoreData[1]); - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .Required(2, kData[2]) @@ -970,6 +955,17 @@ .Required(4, kMoreData[1]) .Required(5, kMoreData[2]); })); + + WriteStringOrDie(kData[0]); + WriteStringOrDie(kData[1]); + WriteStringOrDie(kData[2]); + + // Confirm #1, removing data #0 and #1 + ConfirmOrDie(/*sequencing_id=*/1); + + // Add more data to verify that #2 and new data are returned. + WriteStringOrDie(kMoreData[0]); + WriteStringOrDie(kMoreData[1]); WriteStringOrDie(kMoreData[2]); } @@ -989,10 +985,6 @@ TEST_P(StorageQueueTest, ForceConfirm) { CreateTestStorageQueueOrDie(BuildStorageQueueOptionsPeriodic()); - WriteStringOrDie(kData[0]); - WriteStringOrDie(kData[1]); - WriteStringOrDie(kData[2]); - // Set uploader expectations. EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { @@ -1000,24 +992,11 @@ .Required(0, kData[0]) .Required(1, kData[1]) .Required(2, kData[2]); - })); - // Forward time to trigger upload - task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); - - // Confirm #1 and forward time again, possibly removing records #0 and #1 - ConfirmOrDie(/*sequencing_id=*/1); - // Set uploader expectations. - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client).Required(2, kData[2]); - })); - // Forward time to trigger upload - task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); - - // Now force confirm the very beginning and forward time again. - ConfirmOrDie(/*sequencing_id=*/base::nullopt, /*force=*/true); - // Set uploader expectations: #0 and #1 could be returned as Gaps - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) + // #0 and #1 could be returned as Gaps .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .RequiredSeqId(0) @@ -1030,14 +1009,8 @@ .PossibleGap(0, 2) .Possible(1, kData[1]) .Required(2, kData[2]); - })); - // Forward time to trigger upload - task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); - - // Force confirm #0 and forward time again. - ConfirmOrDie(/*sequencing_id=*/0, /*force=*/true); - // Set uploader expectations: #0 and #1 could be returned as Gaps - EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())) + })) + // #0 and #1 could be returned as Gaps .WillOnce(Invoke([](MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(mock_upload_client) .RequiredSeqId(1) @@ -1048,6 +1021,28 @@ .Possible(1, kData[1]) .Required(2, kData[2]); })); + + WriteStringOrDie(kData[0]); + WriteStringOrDie(kData[1]); + WriteStringOrDie(kData[2]); + + // Forward time to trigger upload + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + + // Confirm #1 and forward time again, possibly removing records #0 and #1 + ConfirmOrDie(/*sequencing_id=*/1); + // Forward time to trigger upload + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + + // Now force confirm the very beginning and forward time again. + ConfirmOrDie(/*sequencing_id=*/base::nullopt, /*force=*/true); + + // Forward time to trigger upload + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + + // Force confirm #0 and forward time again. + ConfirmOrDie(/*sequencing_id=*/0, /*force=*/true); + // Forward time to trigger upload task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); }
diff --git a/components/reporting/storage/storage_unittest.cc b/components/reporting/storage/storage_unittest.cc index 1a71c78..07c9115 100644 --- a/components/reporting/storage/storage_unittest.cc +++ b/components/reporting/storage/storage_unittest.cc
@@ -335,7 +335,7 @@ } private: - Priority priority_; + const Priority priority_; MockUploadClient* const client_; }; @@ -527,7 +527,7 @@ // Initialize Storage with no key. test::TestEvent<StatusOr<scoped_refptr<Storage>>> e; Storage::Create(options, - base::BindRepeating(&StorageTest::BuildMockUploader, + base::BindRepeating(&StorageTest::AsyncStartMockUploader, base::Unretained(this)), encryption_module, e.cb()); ASSIGN_OR_RETURN(auto storage, e.result()); @@ -572,14 +572,15 @@ return options; } - StatusOr<std::unique_ptr<UploaderInterface>> BuildMockUploader( + void AsyncStartMockUploader( Priority priority, - bool need_encryption_key) { + bool need_encryption_key, + UploaderInterface::UploaderInterfaceResultCb start_uploader_cb) { auto uploader = std::make_unique<MockUploadClient>( &last_record_digest_map_, sequenced_task_runner_, decryptor_); set_mock_uploader_expectations_.Call(priority, need_encryption_key, uploader.get()); - return uploader; + std::move(start_uploader_cb).Run(std::move(uploader)); } Status WriteString(Priority priority, base::StringPiece data) { @@ -981,22 +982,14 @@ .Required(0, kData[0]) .Possible(1, kData[1]) .Possible(2, kData[2]); - }))); - WriteStringOrDie(IMMEDIATE, - kData[0]); // Immediately uploads and verifies. - EXPECT_CALL(set_mock_uploader_expectations_, - Call(Eq(IMMEDIATE), /*need_encryption_key=*/Eq(false), NotNull())) + }))) .WillOnce(WithArgs<0, 2>( Invoke([](Priority priority, MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(priority, mock_upload_client) .Required(0, kData[0]) .Required(1, kData[1]) .Possible(2, kData[2]); - }))); - WriteStringOrDie(IMMEDIATE, - kData[1]); // Immediately uploads and verifies. - EXPECT_CALL(set_mock_uploader_expectations_, - Call(Eq(IMMEDIATE), /*need_encryption_key=*/Eq(false), NotNull())) + }))) .WillOnce(WithArgs<0, 2>( Invoke([](Priority priority, MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(priority, mock_upload_client) @@ -1004,6 +997,11 @@ .Required(1, kData[1]) .Required(2, kData[2]); }))); + + WriteStringOrDie(IMMEDIATE, + kData[0]); // Immediately uploads and verifies. + WriteStringOrDie(IMMEDIATE, + kData[1]); // Immediately uploads and verifies. WriteStringOrDie(IMMEDIATE, kData[2]); // Immediately uploads and verifies. } @@ -1023,38 +1021,25 @@ .Possible(0, kData[0]) .Possible(1, kData[1]) .Possible(2, kData[2]); - }))); - WriteStringOrDie(IMMEDIATE, kData[0]); - EXPECT_CALL(set_mock_uploader_expectations_, - Call(Eq(IMMEDIATE), /*need_encryption_key=*/Eq(false), NotNull())) + }))) .WillOnce(WithArgs<0, 2>( Invoke([](Priority priority, MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(priority, mock_upload_client) .Possible(0, kData[0]) .Possible(1, kData[1]) .Possible(2, kData[2]); - }))); - WriteStringOrDie(IMMEDIATE, kData[1]); - EXPECT_CALL(set_mock_uploader_expectations_, - Call(Eq(IMMEDIATE), /*need_encryption_key=*/Eq(false), NotNull())) + }))) .WillOnce(WithArgs<0, 2>( Invoke([](Priority priority, MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(priority, mock_upload_client) .Possible(0, kData[0]) .Possible(1, kData[1]) .Required(2, kData[2]); - }))); - WriteStringOrDie(IMMEDIATE, kData[2]); - - // Confirm #1, removing data #0 and #1 - ConfirmOrDie(IMMEDIATE, /*sequencing_id=*/1); - - // Add more records and verify that #2 and new records are returned. - // Upload is initiated asynchronously, so it may happen after the next - // record is also written. Because of that we set expectations for the - // records after the current one as |Possible|. - EXPECT_CALL(set_mock_uploader_expectations_, - Call(Eq(IMMEDIATE), /*need_encryption_key=*/Eq(false), NotNull())) + }))) + // After adding more data verify that #2 and new data are returned. + // Upload is initiated asynchronously, so it may happen after the next + // record is also written. Because of that we set expectations for the + // data after the current one as |Possible|. .WillOnce(WithArgs<0, 2>( Invoke([](Priority priority, MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(priority, mock_upload_client) @@ -1062,10 +1047,7 @@ .Required(3, kMoreData[0]) .Possible(4, kMoreData[1]) .Possible(5, kMoreData[2]); - }))); - WriteStringOrDie(IMMEDIATE, kMoreData[0]); - EXPECT_CALL(set_mock_uploader_expectations_, - Call(Eq(IMMEDIATE), /*need_encryption_key=*/Eq(false), NotNull())) + }))) .WillOnce(WithArgs<0, 2>( Invoke([](Priority priority, MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(priority, mock_upload_client) @@ -1073,10 +1055,7 @@ .Required(3, kMoreData[0]) .Required(4, kMoreData[1]) .Possible(5, kMoreData[2]); - }))); - WriteStringOrDie(IMMEDIATE, kMoreData[1]); - EXPECT_CALL(set_mock_uploader_expectations_, - Call(Eq(IMMEDIATE), /*need_encryption_key=*/Eq(false), NotNull())) + }))) .WillOnce(WithArgs<0, 2>( Invoke([](Priority priority, MockUploadClient* mock_upload_client) { MockUploadClient::SetUp(priority, mock_upload_client) @@ -1085,6 +1064,17 @@ .Required(4, kMoreData[1]) .Required(5, kMoreData[2]); }))); + + WriteStringOrDie(IMMEDIATE, kData[0]); + WriteStringOrDie(IMMEDIATE, kData[1]); + WriteStringOrDie(IMMEDIATE, kData[2]); + + // Confirm #1, removing data #0 and #1 + ConfirmOrDie(IMMEDIATE, /*sequencing_id=*/1); + + // Add more data to verify that #2 and new data are returned. + WriteStringOrDie(IMMEDIATE, kMoreData[0]); + WriteStringOrDie(IMMEDIATE, kMoreData[1]); WriteStringOrDie(IMMEDIATE, kMoreData[2]); }
diff --git a/components/reporting/storage/storage_uploader_interface.h b/components/reporting/storage/storage_uploader_interface.h index 037fc4c..a672f37b 100644 --- a/components/reporting/storage/storage_uploader_interface.h +++ b/components/reporting/storage/storage_uploader_interface.h
@@ -24,13 +24,24 @@ // automatically discards after |Completed| returns. class UploaderInterface { public: - // Callback type for UploadInterface provider for specified priority. - // |priority| identifies which queue is going to upload the data. - // Set |need_encryption_key| if key is needed (initially or periodically). - using StartCb = - base::RepeatingCallback<StatusOr<std::unique_ptr<UploaderInterface>>( - Priority priority, - bool need_encryption_key)>; + // using AsyncStartUploaderCb = + // base::RepeatingCallback<StatusOr<std::unique_ptr<UploaderInterface>>( + // Priority priority, + // bool need_encryption_key)>; + // Asynchronous callback that instantiates uploader. + // To start upload, call |AsyncStartUploaderCb| on a thread pool. Once + // uploader is instantiated, |AsyncStartUploaderCb| calls its parameter + // passing uploader instance (or error Status). Set |need_encryption_key| if + // key is needed (initially or periodically). + using UploaderInterfaceResultCb = + base::OnceCallback<void(StatusOr<std::unique_ptr<UploaderInterface>>)>; + // Callback type for asynchronous UploadInterface provider. |priority| + // identifies which queue is going to upload the data. + // TODO(b/183666933): |priority| is only used by tests, remove it if possible. + using AsyncStartUploaderCb = + base::RepeatingCallback<void(Priority priority, + bool need_encryption_key, + UploaderInterfaceResultCb)>; UploaderInterface(const UploaderInterface& other) = delete; const UploaderInterface& operator=(const UploaderInterface& other) = delete;
diff --git a/components/resources/policy_resources.grdp b/components/resources/policy_resources.grdp index ec7fc0f..427d31ee 100644 --- a/components/resources/policy_resources.grdp +++ b/components/resources/policy_resources.grdp
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> <include name="IDR_POLICY_CSS" file="../policy/resources/webui/policy.css" preprocess="true" type="BINDATA" /> - <include name="IDR_POLICY_HTML" file="../policy/resources/webui/policy.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> - <include name="IDR_POLICY_BASE_JS" file="../policy/resources/webui/policy_base.js" type="BINDATA" preprocess="true" /> + <include name="IDR_POLICY_HTML" file="../policy/resources/webui/policy.html" type="BINDATA" /> + <include name="IDR_POLICY_BASE_JS" file="../policy/resources/webui/policy_base.js" preprocess="true" type="BINDATA" /> <include name="IDR_POLICY_JS" file="../policy/resources/webui/policy.js" type="BINDATA" /> </grit-part>
diff --git a/components/security_state/content/content_utils.cc b/components/security_state/content/content_utils.cc index 85b2756f..fed2551 100644 --- a/components/security_state/content/content_utils.cc +++ b/components/security_state/content/content_utils.cc
@@ -317,6 +317,7 @@ NOTREACHED(); return; + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kNone: case security_state::SafetyTipStatus::kUnknown: return;
diff --git a/components/security_state/core/security_state.cc b/components/security_state/core/security_state.cc index 844fbda..a517015 100644 --- a/components/security_state/core/security_state.cc +++ b/components/security_state/core/security_state.cc
@@ -54,6 +54,8 @@ return "SafetyTip_BadReputationIgnored"; case security_state::SafetyTipStatus::kLookalikeIgnored: return "SafetyTip_LookalikeIgnored"; + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: + return "SafetyTip_DigitalAssetLinkMatch"; case security_state::SafetyTipStatus::kBadKeyword: return "SafetyTip_BadKeyword"; } @@ -79,6 +81,7 @@ case security_state::SafetyTipStatus::kBadKeyword: // TODO(crbug/1012982): Decide whether to degrade the indicator once the // UI lands. + case security_state::SafetyTipStatus::kDigitalAssetLinkMatch: case security_state::SafetyTipStatus::kUnknown: case security_state::SafetyTipStatus::kNone: return false;
diff --git a/components/security_state/core/security_state.h b/components/security_state/core/security_state.h index 60b6d36..ac0f03c1 100644 --- a/components/security_state/core/security_state.h +++ b/components/security_state/core/security_state.h
@@ -133,7 +133,10 @@ // The current page had a lookalike URL, but a Safety Tip was not shown since // it had been previously ignored by the user. kLookalikeIgnored = 6, - kMaxValue = kLookalikeIgnored, + // Safety tip UI was ignored because of the lookalike's digital asset link + // manifest matched the target's. + kDigitalAssetLinkMatch = 7, + kMaxValue = kDigitalAssetLinkMatch, }; // Information about the last safety tip shown in the UI. This is used in page
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc index 62f2ee54..21a3e93 100644 --- a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc +++ b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
@@ -86,6 +86,7 @@ "model", last_updated_timestamp, syncer::DeviceInfoUtil::GetPulseInterval(), send_tab_to_self_receiving_enabled, /*sharing_info=*/base::nullopt, + /*paask_info=*/base::nullopt, /*fcm_registration_token=*/std::string(), /*interested_data_types=*/syncer::ModelTypeSet()); }
diff --git a/components/send_tab_to_self/target_device_info_unittest.cc b/components/send_tab_to_self/target_device_info_unittest.cc index 525835a..ca02a60 100644 --- a/components/send_tab_to_self/target_device_info_unittest.cc +++ b/components/send_tab_to_self/target_device_info_unittest.cc
@@ -41,6 +41,7 @@ {"sender_id_fcm_token", "sender_id_p256dh", "sender_id_auth_secret"}, std::set<sync_pb::SharingSpecificFields::EnabledFeatures>{ sync_pb::SharingSpecificFields::CLICK_TO_CALL_V2}), + /*paask_info=*/base::nullopt, /*fcm_registration_token=*/std::string(), /*interested_data_types=*/syncer::ModelTypeSet()); }
diff --git a/components/sync/protocol/device_info_specifics.proto b/components/sync/protocol/device_info_specifics.proto index da74199a2..a2843e3 100644 --- a/components/sync/protocol/device_info_specifics.proto +++ b/components/sync/protocol/device_info_specifics.proto
@@ -74,6 +74,10 @@ // Device specific information for Sync invalidations. optional InvalidationSpecificFields invalidation_fields = 14; + + // Information for contacting this device in order to perform security key + // operations. + optional PhoneAsASecurityKeySpecificFields paask_fields = 15; } // Feature specific information about the device that is running a sync-enabled @@ -154,3 +158,28 @@ // components/sync/protocol/sync.proto). repeated int32 interested_data_type_ids = 2; } + +message PhoneAsASecurityKeySpecificFields { + // The encoded tunnel server in the same format as in the BLE advert. See + // device::cablev2::tunnelserver::DecodeDomain. (Actually a uint16 but + // proto doesn't have that as a type.) + optional uint32 tunnel_server_domain = 1; + + // An FCM token that can be presented to the tunnel server to contact this + // device. + optional bytes contact_id = 2; + + // A shared secret key, used to enable communication across devices via + // unauthenticated channels. Knowledge of this secret acts as proof that the + // remote end is authorized to talk to the device publishing this secret. + optional bytes secret = 3; + + // An id that identifies |secret|. This, and |secret|, will be rotated and + // the ID allows this device to know which |secret| the counterparty is + // using. + optional fixed32 id = 4; + + // A P-256, X9.62-encoded public key for this device. Specific to the Chrome + // instance. + optional bytes peer_public_key_x962 = 5; +}
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index 6fefc5f..7c32e69 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -387,6 +387,7 @@ VISIT(feature_fields); VISIT(sharing_fields); VISIT(invalidation_fields); + VISIT(paask_fields); } VISIT_PROTO_FIELDS(const sync_pb::FeatureSpecificFields& proto) { @@ -403,6 +404,15 @@ VISIT_BYTES(sender_id_auth_secret_v2); } +VISIT_PROTO_FIELDS(const sync_pb::PhoneAsASecurityKeySpecificFields& proto) { + VISIT(tunnel_server_domain); + VISIT_BYTES(contact_id); + VISIT(id); + VISIT_BYTES(peer_public_key_x962); + // |secret| is deliberately omitted to avoid including sensitive information + // in debugging output, which might be included in bug reports etc. +} + VISIT_PROTO_FIELDS(const sync_pb::DictionarySpecifics& proto) { VISIT(word); }
diff --git a/components/sync_device_info/device_info.cc b/components/sync_device_info/device_info.cc index 317cd18..df47d3b 100644 --- a/components/sync_device_info/device_info.cc +++ b/components/sync_device_info/device_info.cc
@@ -4,6 +4,8 @@ #include "components/sync_device_info/device_info.h" +#include <utility> + #include "base/values.h" namespace syncer { @@ -37,20 +39,40 @@ enabled_features == other.enabled_features; } -DeviceInfo::DeviceInfo(const std::string& guid, - const std::string& client_name, - const std::string& chrome_version, - const std::string& sync_user_agent, - const sync_pb::SyncEnums::DeviceType device_type, - const std::string& signin_scoped_device_id, - const std::string& manufacturer_name, - const std::string& model_name, - base::Time last_updated_timestamp, - base::TimeDelta pulse_interval, - bool send_tab_to_self_receiving_enabled, - const base::Optional<SharingInfo>& sharing_info, - const std::string& fcm_registration_token, - const ModelTypeSet& interested_data_types) +DeviceInfo::PhoneAsASecurityKeyInfo::PhoneAsASecurityKeyInfo() = default; +DeviceInfo::PhoneAsASecurityKeyInfo::PhoneAsASecurityKeyInfo( + const DeviceInfo::PhoneAsASecurityKeyInfo& other) = default; +DeviceInfo::PhoneAsASecurityKeyInfo::PhoneAsASecurityKeyInfo( + DeviceInfo::PhoneAsASecurityKeyInfo&& other) = default; +DeviceInfo::PhoneAsASecurityKeyInfo& +DeviceInfo::PhoneAsASecurityKeyInfo::operator=( + const DeviceInfo::PhoneAsASecurityKeyInfo& other) = default; +DeviceInfo::PhoneAsASecurityKeyInfo::~PhoneAsASecurityKeyInfo() = default; + +bool DeviceInfo::PhoneAsASecurityKeyInfo::operator==( + const PhoneAsASecurityKeyInfo& other) const { + // This can just be a default function once C++20 is available. + return tunnel_server_domain == other.tunnel_server_domain && + contact_id == other.contact_id && secret == other.secret && + id == other.id && peer_public_key_x962 == other.peer_public_key_x962; +} + +DeviceInfo::DeviceInfo( + const std::string& guid, + const std::string& client_name, + const std::string& chrome_version, + const std::string& sync_user_agent, + const sync_pb::SyncEnums::DeviceType device_type, + const std::string& signin_scoped_device_id, + const std::string& manufacturer_name, + const std::string& model_name, + base::Time last_updated_timestamp, + base::TimeDelta pulse_interval, + bool send_tab_to_self_receiving_enabled, + const base::Optional<SharingInfo>& sharing_info, + const base::Optional<PhoneAsASecurityKeyInfo>& paask_info, + const std::string& fcm_registration_token, + const ModelTypeSet& interested_data_types) : guid_(guid), client_name_(client_name), chrome_version_(chrome_version), @@ -63,6 +85,7 @@ pulse_interval_(pulse_interval), send_tab_to_self_receiving_enabled_(send_tab_to_self_receiving_enabled), sharing_info_(sharing_info), + paask_info_(paask_info), fcm_registration_token_(fcm_registration_token), interested_data_types_(interested_data_types) {} @@ -121,6 +144,11 @@ return sharing_info_; } +const base::Optional<DeviceInfo::PhoneAsASecurityKeyInfo>& +DeviceInfo::paask_info() const { + return paask_info_; +} + std::string DeviceInfo::GetOSString() const { switch (device_type_) { case sync_pb::SyncEnums_DeviceType_TYPE_WIN: @@ -179,6 +207,7 @@ this->send_tab_to_self_receiving_enabled() == other.send_tab_to_self_receiving_enabled() && this->sharing_info() == other.sharing_info() && + this->paask_info() == other.paask_info() && this->fcm_registration_token() == other.fcm_registration_token() && this->interested_data_types() == other.interested_data_types(); } @@ -210,6 +239,10 @@ sharing_info_ = sharing_info; } +void DeviceInfo::set_paask_info(PhoneAsASecurityKeyInfo&& paask_info) { + paask_info_.emplace(std::forward<PhoneAsASecurityKeyInfo>(paask_info)); +} + void DeviceInfo::set_client_name(const std::string& client_name) { client_name_ = client_name; }
diff --git a/components/sync_device_info/device_info.h b/components/sync_device_info/device_info.h index ae651863..76a950ec 100644 --- a/components/sync_device_info/device_info.h +++ b/components/sync_device_info/device_info.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SYNC_DEVICE_INFO_DEVICE_INFO_H_ #define COMPONENTS_SYNC_DEVICE_INFO_DEVICE_INFO_H_ +#include <array> #include <memory> #include <set> #include <string> @@ -63,6 +64,31 @@ bool operator==(const SharingInfo& other) const; }; + struct PhoneAsASecurityKeyInfo { + PhoneAsASecurityKeyInfo(); + PhoneAsASecurityKeyInfo(const PhoneAsASecurityKeyInfo& other); + PhoneAsASecurityKeyInfo(PhoneAsASecurityKeyInfo&& other); + PhoneAsASecurityKeyInfo& operator=(const PhoneAsASecurityKeyInfo& other); + ~PhoneAsASecurityKeyInfo(); + + bool operator==(const PhoneAsASecurityKeyInfo& other) const; + + // The domain of the tunnel service. See + // |device::cablev2::tunnelserver::DecodeDomain| to decode this value. + uint16_t tunnel_server_domain; + // contact_id is an opaque value that is sent to the tunnel service in order + // to identify the caBLEv2 authenticator. + std::vector<uint8_t> contact_id; + // secret is the shared secret that authenticates the desktop to the + // authenticator. + std::array<uint8_t, 32> secret; + // id identifies the secret so that the phone knows which secret to use + // for a given connection. + uint32_t id; + // peer_public_key_x962 is the authenticator's public key. + std::array<uint8_t, 65> peer_public_key_x962; + }; + DeviceInfo(const std::string& guid, const std::string& client_name, const std::string& chrome_version, @@ -75,6 +101,7 @@ base::TimeDelta pulse_interval, bool send_tab_to_self_receiving_enabled, const base::Optional<SharingInfo>& sharing_info, + const base::Optional<PhoneAsASecurityKeyInfo>& paask_info, const std::string& fcm_registration_token, const ModelTypeSet& interested_data_types); ~DeviceInfo(); @@ -126,6 +153,8 @@ // Returns Sharing related info of the device. const base::Optional<SharingInfo>& sharing_info() const; + const base::Optional<PhoneAsASecurityKeyInfo>& paask_info() const; + // Returns the FCM registration token for sync invalidations. const std::string& fcm_registration_token() const; @@ -151,6 +180,8 @@ void set_sharing_info(const base::Optional<SharingInfo>& sharing_info); + void set_paask_info(PhoneAsASecurityKeyInfo&& paask_info); + void set_client_name(const std::string& client_name); void set_fcm_registration_token(const std::string& fcm_token); @@ -192,6 +223,8 @@ base::Optional<SharingInfo> sharing_info_; + base::Optional<PhoneAsASecurityKeyInfo> paask_info_; + // An FCM registration token obtained by sync invalidations service. std::string fcm_registration_token_;
diff --git a/components/sync_device_info/device_info_sync_bridge.cc b/components/sync_device_info/device_info_sync_bridge.cc index fb52827f..69a8548d 100644 --- a/components/sync_device_info/device_info_sync_bridge.cc +++ b/components/sync_device_info/device_info_sync_bridge.cc
@@ -86,6 +86,43 @@ std::move(enabled_features)); } +std::vector<uint8_t> VectorFromString(const std::string& s) { + const uint8_t* ptr = reinterpret_cast<const uint8_t*>(s.data()); + return std::vector<uint8_t>(ptr, ptr + s.size()); +} + +base::Optional<DeviceInfo::PhoneAsASecurityKeyInfo> +SpecificsToPhoneAsASecurityKeyInfo(const DeviceInfoSpecifics& specifics) { + if (!specifics.has_paask_fields()) { + return base::nullopt; + } + + DeviceInfo::PhoneAsASecurityKeyInfo to; + const auto& from = specifics.paask_fields(); + if (!from.has_tunnel_server_domain() || !from.has_id() || + !from.has_contact_id() || !from.has_secret() || + !from.has_peer_public_key_x962() || + from.tunnel_server_domain() >= 0x10000) { + return base::nullopt; + } + to.tunnel_server_domain = from.tunnel_server_domain(); + to.id = from.id(); + to.contact_id = VectorFromString(from.contact_id()); + + if (from.secret().size() != to.secret.size()) { + return base::nullopt; + } + memcpy(to.secret.data(), from.secret().data(), to.secret.size()); + + if (from.peer_public_key_x962().size() != to.peer_public_key_x962.size()) { + return base::nullopt; + } + memcpy(to.peer_public_key_x962.data(), from.peer_public_key_x962().data(), + to.peer_public_key_x962.size()); + + return to; +} + // Converts DeviceInfoSpecifics into a freshly allocated DeviceInfo. std::unique_ptr<DeviceInfo> SpecificsToModel( const DeviceInfoSpecifics& specifics) { @@ -109,6 +146,7 @@ GetPulseIntervalFromSpecifics(specifics), specifics.feature_fields().send_tab_to_self_receiving_enabled(), SpecificsToSharingInfo(specifics), + SpecificsToPhoneAsASecurityKeyInfo(specifics), specifics.invalidation_fields().instance_id_token(), data_types); } @@ -121,6 +159,19 @@ return entity_data; } +sync_pb::PhoneAsASecurityKeySpecificFields PhoneAsASecurityKeyInfoToProto( + const DeviceInfo::PhoneAsASecurityKeyInfo& paask_info) { + sync_pb::PhoneAsASecurityKeySpecificFields paask_fields; + paask_fields.set_tunnel_server_domain(paask_info.tunnel_server_domain); + paask_fields.set_contact_id(paask_info.contact_id.data(), + paask_info.contact_id.size()); + paask_fields.set_secret(paask_info.secret.data(), paask_info.secret.size()); + paask_fields.set_id(paask_info.id); + paask_fields.set_peer_public_key_x962(paask_info.peer_public_key_x962.data(), + paask_info.peer_public_key_x962.size()); + return paask_fields; +} + // Converts a local DeviceInfo into a freshly allocated DeviceInfoSpecifics. std::unique_ptr<DeviceInfoSpecifics> MakeLocalDeviceSpecifics( const DeviceInfo& info) { @@ -164,6 +215,13 @@ } } + const base::Optional<DeviceInfo::PhoneAsASecurityKeyInfo>& paask_info = + info.paask_info(); + if (paask_info) { + *specifics->mutable_paask_fields() = + PhoneAsASecurityKeyInfoToProto(*paask_info); + } + // Set sync invalidations FCM registration token and interested data types. if (!info.fcm_registration_token().empty()) { specifics->mutable_invalidation_fields()->set_instance_id_token(
diff --git a/components/sync_device_info/device_info_sync_bridge_unittest.cc b/components/sync_device_info/device_info_sync_bridge_unittest.cc index abe0b5b..c98a2f41 100644 --- a/components/sync_device_info/device_info_sync_bridge_unittest.cc +++ b/components/sync_device_info/device_info_sync_bridge_unittest.cc
@@ -368,7 +368,8 @@ SharingSenderIdP256dhForSuffix(kLocalSuffix), SharingSenderIdAuthSecretForSuffix(kLocalSuffix)}, sharing_enabled_features), - last_fcm_registration_token, last_interested_data_types); + /*paask_info=*/base::nullopt, last_fcm_registration_token, + last_interested_data_types); } void Clear() override { local_device_info_.reset(); }
diff --git a/components/sync_device_info/device_info_sync_client.h b/components/sync_device_info/device_info_sync_client.h index 1f9a094..0de06829b 100644 --- a/components/sync_device_info/device_info_sync_client.h +++ b/components/sync_device_info/device_info_sync_client.h
@@ -33,6 +33,10 @@ // not initialized yet. virtual base::Optional<ModelTypeSet> GetInterestedDataTypes() const = 0; + // Return registration information for using a phone-as-a-security-key. + virtual base::Optional<DeviceInfo::PhoneAsASecurityKeyInfo> + GetPhoneAsASecurityKeyInfo() const = 0; + private: DISALLOW_COPY_AND_ASSIGN(DeviceInfoSyncClient); };
diff --git a/components/sync_device_info/device_info_sync_service_impl.h b/components/sync_device_info/device_info_sync_service_impl.h index 55b41bb..b2209da 100644 --- a/components/sync_device_info/device_info_sync_service_impl.h +++ b/components/sync_device_info/device_info_sync_service_impl.h
@@ -60,7 +60,7 @@ std::unique_ptr<DeviceInfoSyncClient> device_info_sync_client_; std::unique_ptr<DeviceInfoSyncBridge> bridge_; - SyncInvalidationsService* sync_invalidations_service_; + SyncInvalidationsService* const sync_invalidations_service_; DISALLOW_COPY_AND_ASSIGN(DeviceInfoSyncServiceImpl); };
diff --git a/components/sync_device_info/fake_device_info_tracker.cc b/components/sync_device_info/fake_device_info_tracker.cc index c998adc..c72a31f 100644 --- a/components/sync_device_info/fake_device_info_tracker.cc +++ b/components/sync_device_info/fake_device_info_tracker.cc
@@ -20,7 +20,8 @@ device_info.manufacturer_name(), device_info.model_name(), device_info.last_updated_timestamp(), device_info.pulse_interval(), device_info.send_tab_to_self_receiving_enabled(), - device_info.sharing_info(), device_info.fcm_registration_token(), + device_info.sharing_info(), device_info.paask_info(), + device_info.fcm_registration_token(), device_info.interested_data_types()); }
diff --git a/components/sync_device_info/fake_local_device_info_provider.cc b/components/sync_device_info/fake_local_device_info_provider.cc index 208a4f1..baf795a 100644 --- a/components/sync_device_info/fake_local_device_info_provider.cc +++ b/components/sync_device_info/fake_local_device_info_provider.cc
@@ -23,6 +23,7 @@ DeviceInfoUtil::GetPulseInterval(), /*send_tab_to_self_receiving_enabled=*/false, /*sharing_info=*/base::nullopt, + /*paask_info=*/base::nullopt, /*fcm_registration_token=*/std::string(), /*interested_data_types=*/ModelTypeSet()) {}
diff --git a/components/sync_device_info/local_device_info_provider_impl.cc b/components/sync_device_info/local_device_info_provider_impl.cc index b5f562df..f61be11 100644 --- a/components/sync_device_info/local_device_info_provider_impl.cc +++ b/components/sync_device_info/local_device_info_provider_impl.cc
@@ -57,6 +57,12 @@ local_device_info_->set_interested_data_types(*interested_data_types); } + base::Optional<DeviceInfo::PhoneAsASecurityKeyInfo> paask_info = + sync_client_->GetPhoneAsASecurityKeyInfo(); + if (paask_info) { + local_device_info_->set_paask_info(std::move(*paask_info)); + } + return local_device_info_.get(); } @@ -83,11 +89,13 @@ // become ready by then. std::string last_fcm_registration_token; ModelTypeSet last_interested_data_types; + base::Optional<DeviceInfo::PhoneAsASecurityKeyInfo> paask_info; if (device_info_restored_from_store) { last_fcm_registration_token = device_info_restored_from_store->fcm_registration_token(); last_interested_data_types = device_info_restored_from_store->interested_data_types(); + paask_info = device_info_restored_from_store->paask_info(); } // The local device doesn't have a last updated timestamps. It will be set in @@ -99,8 +107,8 @@ /*last_updated_timestamp=*/base::Time(), DeviceInfoUtil::GetPulseInterval(), sync_client_->GetSendTabToSelfReceivingEnabled(), - sync_client_->GetLocalSharingInfo(), last_fcm_registration_token, - last_interested_data_types); + sync_client_->GetLocalSharingInfo(), paask_info, + last_fcm_registration_token, last_interested_data_types); // Notify observers. closure_list_.Notify();
diff --git a/components/sync_device_info/local_device_info_provider_impl_unittest.cc b/components/sync_device_info/local_device_info_provider_impl_unittest.cc index 07dcfc0..caf7aeda 100644 --- a/components/sync_device_info/local_device_info_provider_impl_unittest.cc +++ b/components/sync_device_info/local_device_info_provider_impl_unittest.cc
@@ -47,6 +47,10 @@ GetLocalSharingInfo, (), (const override)); + MOCK_METHOD(base::Optional<DeviceInfo::PhoneAsASecurityKeyInfo>, + GetPhoneAsASecurityKeyInfo, + (), + (const override)); MOCK_METHOD(base::Optional<std::string>, GetFCMRegistrationToken, (), @@ -83,6 +87,16 @@ /*device_info_restored_from_store=*/nullptr); } + DeviceInfo::PhoneAsASecurityKeyInfo SamplePhoneAsASecurityKeyInfo() { + DeviceInfo::PhoneAsASecurityKeyInfo paask_info; + paask_info.tunnel_server_domain = 123; + paask_info.contact_id = {1, 2, 3, 4}; + paask_info.secret = {5, 6, 7, 8}; + paask_info.id = 321; + paask_info.peer_public_key_x962 = {10, 11, 12, 13}; + return paask_info; + } + testing::NiceMock<MockDeviceInfoSyncClient> device_info_sync_client_; std::unique_ptr<LocalDeviceInfoProviderImpl> provider_; }; @@ -208,17 +222,19 @@ const std::string kFCMRegistrationToken = "fcm_token"; const ModelTypeSet kInterestedDataTypes(BOOKMARKS); + DeviceInfo::PhoneAsASecurityKeyInfo paask_info = + SamplePhoneAsASecurityKeyInfo(); auto device_info_restored_from_store = std::make_unique<DeviceInfo>( kLocalDeviceGuid, "name", "chrome_version", "user_agent", sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", "manufacturer", "model", base::Time(), base::TimeDelta::FromDays(1), /*send_tab_to_self_receiving_enabled=*/true, - /*sharing_info=*/base::nullopt, kFCMRegistrationToken, + /*sharing_info=*/base::nullopt, paask_info, kFCMRegistrationToken, kInterestedDataTypes); - // |kFCMRegistrationToken| and |kInterestedDataTypes| should be taken from - // |device_info_restored_from_store| when |device_info_sync_client_| returns - // nullopt. + // |kFCMRegistrationToken|, |kInterestedDataTypes|, and |paask_info| should be + // taken from |device_info_restored_from_store| when + // |device_info_sync_client_| returns nullopt. provider_->Initialize(kLocalDeviceGuid, kLocalDeviceClientName, kLocalDeviceManufacturerName, kLocalDeviceModelName, std::move(device_info_restored_from_store)); @@ -227,10 +243,40 @@ .WillOnce(Return(base::nullopt)); EXPECT_CALL(device_info_sync_client_, GetInterestedDataTypes()) .WillOnce(Return(base::nullopt)); + EXPECT_CALL(device_info_sync_client_, GetPhoneAsASecurityKeyInfo()) + .WillOnce(Return(base::nullopt)); const DeviceInfo* local_device_info = provider_->GetLocalDeviceInfo(); EXPECT_EQ(local_device_info->interested_data_types(), kInterestedDataTypes); EXPECT_EQ(local_device_info->fcm_registration_token(), kFCMRegistrationToken); + EXPECT_EQ(local_device_info->paask_info(), paask_info); +} + +TEST_F(LocalDeviceInfoProviderImplTest, PhoneAsASecurityKeyInfo) { + ON_CALL(device_info_sync_client_, GetPhoneAsASecurityKeyInfo()) + .WillByDefault(Return(base::nullopt)); + + InitializeProvider(); + + ASSERT_THAT(provider_->GetLocalDeviceInfo(), NotNull()); + EXPECT_FALSE(provider_->GetLocalDeviceInfo()->paask_info()); + + DeviceInfo::PhoneAsASecurityKeyInfo paask_info = + SamplePhoneAsASecurityKeyInfo(); + ON_CALL(device_info_sync_client_, GetPhoneAsASecurityKeyInfo()) + .WillByDefault(Return(paask_info)); + + ASSERT_THAT(provider_->GetLocalDeviceInfo(), NotNull()); + const base::Optional<DeviceInfo::PhoneAsASecurityKeyInfo>& result_paask_info = + provider_->GetLocalDeviceInfo()->paask_info(); + ASSERT_TRUE(result_paask_info); + EXPECT_EQ(paask_info.tunnel_server_domain, + result_paask_info->tunnel_server_domain); + EXPECT_EQ(paask_info.contact_id, result_paask_info->contact_id); + EXPECT_EQ(paask_info.secret, result_paask_info->secret); + EXPECT_EQ(paask_info.id, result_paask_info->id); + EXPECT_EQ(paask_info.peer_public_key_x962, + result_paask_info->peer_public_key_x962); } } // namespace
diff --git a/components/test/data/autofill/heuristics/output/020_checkout_cafepress.com.out b/components/test/data/autofill/heuristics/output/020_checkout_cafepress.com.out index bc4a863..e69ce64 100644 --- a/components/test/data/autofill/heuristics/output/020_checkout_cafepress.com.out +++ b/components/test/data/autofill/heuristics/output/020_checkout_cafepress.com.out
@@ -24,7 +24,7 @@ UNKNOWN_TYPE | GiftMessage | One message per order You have | | ShipName_2-default UNKNOWN_TYPE | countdown | You have | 300 | ShipName_2-default UNKNOWN_TYPE | ApplyGiftWrap | (+$0.00) | on | ShipName_2-default -UNKNOWN_TYPE | txtCoupon | Apply Promo Code | | ShipName_2-default +MERCHANT_PROMO_CODE | txtCoupon | Apply Promo Code | | ShipName_2-default UNKNOWN_TYPE | PaymentMethod | PayByCafeCash | PayByCafeCash | ShipName_2-default UNKNOWN_TYPE | PaymentMethod | PayByGC | PayByGC | ShipName_2-default UNKNOWN_TYPE | PaymentMethod | PayByCCGC | PayByCCGC | ShipName_2-default
diff --git a/components/translate/core/browser/translate_pref_names.cc b/components/translate/core/browser/translate_pref_names.cc index 96fe2c1..de4c2df0 100644 --- a/components/translate/core/browser/translate_pref_names.cc +++ b/components/translate/core/browser/translate_pref_names.cc
@@ -4,6 +4,8 @@ #include "components/translate/core/browser/translate_pref_names.h" +// These preferences are included in java_pref_names_srcjar for access in +// Java code. namespace prefs { // Boolean that is true when offering translate (i.e. the automatic translate @@ -11,4 +13,6 @@ // from the right-click context menu unless translate is disabled by policy. const char kOfferTranslateEnabled[] = "translate.enabled"; +const char kPrefAlwaysTranslateList[] = "translate_whitelists"; + } // namespace prefs
diff --git a/components/translate/core/browser/translate_pref_names.h b/components/translate/core/browser/translate_pref_names.h index b33849e..9c4b27c6 100644 --- a/components/translate/core/browser/translate_pref_names.h +++ b/components/translate/core/browser/translate_pref_names.h
@@ -8,6 +8,7 @@ namespace prefs { extern const char kOfferTranslateEnabled[]; +extern const char kPrefAlwaysTranslateList[]; } // namespace prefs
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc index 5dabc504..4b2b7cdd 100644 --- a/components/translate/core/browser/translate_prefs.cc +++ b/components/translate/core/browser/translate_prefs.cc
@@ -87,7 +87,6 @@ "translate_site_blacklist"; const char TranslatePrefs::kPrefNeverPromptSitesWithTime[] = "translate_site_blacklist_with_time"; -const char TranslatePrefs::kPrefAlwaysTranslateLists[] = "translate_whitelists"; const char TranslatePrefs::kPrefTranslateDeniedCount[] = "translate_denied_count_for_language"; const char TranslatePrefs::kPrefTranslateIgnoredCount[] = @@ -559,7 +558,7 @@ base::StringPiece original_language, base::StringPiece target_language) { const base::DictionaryValue* dict = - prefs_->GetDictionary(kPrefAlwaysTranslateLists); + prefs_->GetDictionary(prefs::kPrefAlwaysTranslateList); if (dict) { const std::string* auto_target_lang = dict->FindStringKey(original_language); @@ -572,7 +571,7 @@ void TranslatePrefs::AddLanguagePairToAlwaysTranslateList( base::StringPiece original_language, base::StringPiece target_language) { - DictionaryPrefUpdate update(prefs_, kPrefAlwaysTranslateLists); + DictionaryPrefUpdate update(prefs_, prefs::kPrefAlwaysTranslateList); base::DictionaryValue* dict = update.Get(); if (!dict) { NOTREACHED() << "Always translate pref is unregistered"; @@ -584,7 +583,7 @@ void TranslatePrefs::RemoveLanguagePairFromAlwaysTranslateList( base::StringPiece original_language, base::StringPiece target_language) { - DictionaryPrefUpdate update(prefs_, kPrefAlwaysTranslateLists); + DictionaryPrefUpdate update(prefs_, prefs::kPrefAlwaysTranslateList); base::DictionaryValue* dict = update.Get(); if (!dict) { NOTREACHED() << "Always translate pref is unregistered"; @@ -607,7 +606,7 @@ std::vector<std::string> TranslatePrefs::GetAlwaysTranslateLanguages() const { const base::DictionaryValue* dict = - prefs_->GetDictionary(kPrefAlwaysTranslateLists); + prefs_->GetDictionary(prefs::kPrefAlwaysTranslateList); if (!dict) { NOTREACHED() << "Always translate pref is unregistered"; } @@ -635,11 +634,11 @@ } bool TranslatePrefs::HasLanguagePairsToAlwaysTranslate() const { - return !IsDictionaryEmpty(kPrefAlwaysTranslateLists); + return !IsDictionaryEmpty(prefs::kPrefAlwaysTranslateList); } void TranslatePrefs::ClearAlwaysTranslateLanguagePairs() { - prefs_->ClearPref(kPrefAlwaysTranslateLists); + prefs_->ClearPref(prefs::kPrefAlwaysTranslateList); } int TranslatePrefs::GetTranslationDeniedCount( @@ -843,7 +842,7 @@ bool TranslatePrefs::ShouldAutoTranslate(base::StringPiece original_language, std::string* target_language) { const base::DictionaryValue* dict = - prefs_->GetDictionary(kPrefAlwaysTranslateLists); + prefs_->GetDictionary(prefs::kPrefAlwaysTranslateList); if (dict && dict->GetString(original_language, target_language)) { DCHECK(!target_language->empty()); return !target_language->empty(); @@ -889,7 +888,7 @@ kPrefNeverPromptSitesWithTime, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterDictionaryPref( - kPrefAlwaysTranslateLists, + prefs::kPrefAlwaysTranslateList, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterDictionaryPref( kPrefTranslateDeniedCount,
diff --git a/components/translate/core/browser/translate_prefs.h b/components/translate/core/browser/translate_prefs.h index 3d2797f..449f2f0 100644 --- a/components/translate/core/browser/translate_prefs.h +++ b/components/translate/core/browser/translate_prefs.h
@@ -131,7 +131,6 @@ // 3 milestones (M74). static const char kPrefNeverPromptSitesDeprecated[]; static const char kPrefNeverPromptSitesWithTime[]; - static const char kPrefAlwaysTranslateLists[]; static const char kPrefTranslateDeniedCount[]; static const char kPrefTranslateIgnoredCount[]; static const char kPrefTranslateAcceptedCount[];
diff --git a/components/translate/translate_internals/translate_internals_handler.cc b/components/translate/translate_internals/translate_internals_handler.cc index 10ac9766..4ce77a4 100644 --- a/components/translate/translate_internals/translate_internals_handler.cc +++ b/components/translate/translate_internals/translate_internals_handler.cc
@@ -245,7 +245,7 @@ translate::TranslatePrefs::kPrefTranslateRecentTarget, translate::TranslatePrefs::kPrefNeverPromptSitesDeprecated, translate::TranslatePrefs::kPrefNeverPromptSitesWithTime, - translate::TranslatePrefs::kPrefAlwaysTranslateLists, + prefs::kPrefAlwaysTranslateList, translate::TranslatePrefs::kPrefTranslateDeniedCount, translate::TranslatePrefs::kPrefTranslateIgnoredCount, translate::TranslatePrefs::kPrefTranslateAcceptedCount,
diff --git a/components/vector_icons/cc_macros.h b/components/vector_icons/cc_macros.h index 83b8a9d..43ae8ed 100644 --- a/components/vector_icons/cc_macros.h +++ b/components/vector_icons/cc_macros.h
@@ -29,7 +29,7 @@ #define VECTOR_ICON_TEMPLATE_CC(rep_list_name, icon_name, ...) \ constexpr char icon_name##Id[] = VECTOR_ICON_ID_PREFIX #icon_name; \ static constexpr gfx::VectorIconRep rep_list_name[] = {__VA_ARGS__}; \ - VECTOR_ICON_EXPORT const gfx::VectorIcon icon_name = { \ + VECTOR_ICON_EXPORT constexpr gfx::VectorIcon icon_name = { \ rep_list_name, base::size(rep_list_name), icon_name##Id}; #else // !COMPONENTS_VECTOR_ICONS_CC_MACROS_H_
diff --git a/components/viz/common/quads/compositor_frame_metadata_unittest.cc b/components/viz/common/quads/compositor_frame_metadata_unittest.cc index c4afe57..54be107 100644 --- a/components/viz/common/quads/compositor_frame_metadata_unittest.cc +++ b/components/viz/common/quads/compositor_frame_metadata_unittest.cc
@@ -51,7 +51,7 @@ bool AreTransitionDirectivesEqual(const CompositorFrameTransitionDirective& a, const CompositorFrameTransitionDirective& b) { return a.sequence_id() == b.sequence_id() && a.type() == b.type() && - a.effect() == b.effect() && a.duration() == b.duration(); + a.effect() == b.effect(); } TEST(CompositorFrameMetadata, Clone) { @@ -90,8 +90,7 @@ gfx::RectF(1, 2, 3, 4), true); metadata.transition_directives.emplace_back( 4u, CompositorFrameTransitionDirective::Type::kSave, - CompositorFrameTransitionDirective::Effect::kCoverUp, - base::TimeDelta::FromMilliseconds(321)); + CompositorFrameTransitionDirective::Effect::kCoverUp); CompositorFrameMetadata clone = metadata.Clone(); EXPECT_FLOAT_EQ(clone.device_scale_factor, metadata.device_scale_factor);
diff --git a/components/viz/common/quads/compositor_frame_transition_directive.cc b/components/viz/common/quads/compositor_frame_transition_directive.cc index 94a967a5..562564fe 100644 --- a/components/viz/common/quads/compositor_frame_transition_directive.cc +++ b/components/viz/common/quads/compositor_frame_transition_directive.cc
@@ -10,8 +10,6 @@ namespace viz { -constexpr base::TimeDelta CompositorFrameTransitionDirective::kMaxDuration; - CompositorFrameTransitionDirective::CompositorFrameTransitionDirective() = default; @@ -19,15 +17,11 @@ uint32_t sequence_id, Type type, Effect effect, - base::TimeDelta duration, std::vector<CompositorRenderPassId> shared_render_pass_ids) : sequence_id_(sequence_id), type_(type), effect_(effect), - duration_(duration), - shared_render_pass_ids_(std::move(shared_render_pass_ids)) { - DCHECK_LE(duration_, kMaxDuration); -} + shared_render_pass_ids_(std::move(shared_render_pass_ids)) {} CompositorFrameTransitionDirective::CompositorFrameTransitionDirective( const CompositorFrameTransitionDirective&) = default;
diff --git a/components/viz/common/quads/compositor_frame_transition_directive.h b/components/viz/common/quads/compositor_frame_transition_directive.h index afe1b4e9..8997389 100644 --- a/components/viz/common/quads/compositor_frame_transition_directive.h +++ b/components/viz/common/quads/compositor_frame_transition_directive.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/time/time.h" #include "components/viz/common/quads/compositor_render_pass.h" #include "components/viz/common/viz_common_export.h" @@ -44,20 +43,15 @@ kRevealUp }; - // This is the maximum allowable transition duration. - static constexpr base::TimeDelta kMaxDuration = - base::TimeDelta::FromMilliseconds(500); - CompositorFrameTransitionDirective(); - // Constructs a new directive. Note that if type is `kSave`, the effect and - // duration should be specified for a desired effect. These are ignored for - // the `kAnimate` type. + // Constructs a new directive. Note that if type is `kSave`, the effect should + // be specified for a desired effect. These are ignored for the `kAnimate` + // type. CompositorFrameTransitionDirective( uint32_t sequence_id, Type type, Effect effect = Effect::kNone, - base::TimeDelta duration = {}, std::vector<CompositorRenderPassId> shared_render_pass_ids = {}); CompositorFrameTransitionDirective(const CompositorFrameTransitionDirective&); @@ -74,9 +68,6 @@ // The type of this directive. Type type() const { return type_; } - // The duration of the animation. Note that this is at most kMaxDuration. - base::TimeDelta duration() const { return duration_; } - // The effect for the transition. Effect effect() const { return effect_; } @@ -92,8 +83,6 @@ Effect effect_ = Effect::kNone; - base::TimeDelta duration_; - std::vector<CompositorRenderPassId> shared_render_pass_ids_; };
diff --git a/components/viz/common/quads/compositor_frame_transition_directive_unittest.cc b/components/viz/common/quads/compositor_frame_transition_directive_unittest.cc index 1df5f7bd..66e92a0 100644 --- a/components/viz/common/quads/compositor_frame_transition_directive_unittest.cc +++ b/components/viz/common/quads/compositor_frame_transition_directive_unittest.cc
@@ -13,14 +13,12 @@ using Type = CompositorFrameTransitionDirective::Type; TEST(CompositorFrameTransitionDirective, GettersReflectParameters) { - CompositorFrameTransitionDirective save_directive( - 1u, Type::kSave, Effect::kCoverLeft, - base::TimeDelta::FromMilliseconds(100)); + CompositorFrameTransitionDirective save_directive(1u, Type::kSave, + Effect::kCoverLeft); EXPECT_EQ(1u, save_directive.sequence_id()); EXPECT_EQ(Type::kSave, save_directive.type()); EXPECT_EQ(Effect::kCoverLeft, save_directive.effect()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(100), save_directive.duration()); CompositorFrameTransitionDirective animate_directive(2, Type::kAnimate);
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc index 5d6a31a6..5d37e8f 100644 --- a/components/viz/service/display/surface_aggregator_unittest.cc +++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -8983,8 +8983,7 @@ auto frame = BuildCompositorFrameWithResources({}, true, SurfaceId()); frame.metadata.transition_directives.emplace_back( 1, CompositorFrameTransitionDirective::Type::kSave, - CompositorFrameTransitionDirective::Effect::kCoverLeft, - base::TimeDelta::FromMilliseconds(500)); + CompositorFrameTransitionDirective::Effect::kCoverLeft); support->SubmitCompositorFrame(local_surface_id, std::move(frame)); auto* surface = support->GetLastCreatedSurfaceForTesting();
diff --git a/components/viz/service/transitions/surface_animation_manager.cc b/components/viz/service/transitions/surface_animation_manager.cc index 74b5668..ad8e3fe 100644 --- a/components/viz/service/transitions/surface_animation_manager.cc +++ b/components/viz/service/transitions/surface_animation_manager.cc
@@ -26,20 +26,16 @@ return CompositorRenderPassId(id.GetUnsafeValue() + 1); } -constexpr base::TimeDelta kMinimumAnimationDuration = - base::TimeDelta::FromMilliseconds(50); +constexpr base::TimeDelta kDefaultAnimationDuration = + base::TimeDelta::FromMilliseconds(300); -// TODO(vmpstr): if we decide upon hard-coded animation durations per -// (https://github.com/vmpstr/shared-element-transitions/issues/9), 500ms for -// transform transitions and 400ms for opacity transitions (staggered) produces -// appealing results. For the time being, we will scale the overall duration to -// produce the opacity duration. Opacity transitions which reveal an element -// (i.e., transition opacity from 0 -> 1) should finish ahead of a translation. -// This way, you'll see the next page fade into view and settle -// while fully opaque. Similarly, transitions which hide an element (i.e., -// transition opacity from 1 -> 0) should, for a brief period, animate with -// full opacity so the user can get a sense of the -// motion before the element disappears. +// Scale the overall duration to produce the opacity duration. Opacity +// transitions which reveal an element (i.e., transition opacity from 0 -> 1) +// should finish ahead of a translation. This way, you'll see the next page fade +// into view and settle while fully opaque. Similarly, transitions which hide an +// element (i.e., transition opacity from 1 -> 0) should, for a brief period, +// animate with full opacity so the user can get a sense of the motion before +// the element disappears. constexpr float kOpacityTransitionDurationScaleFactor = 0.8f; // When performing slides, the amount moved is proportional to the minimum @@ -472,8 +468,7 @@ : gfx::CubicBezierTimingFunction::EaseType::EASE_OUT); // Create the transform curve. - base::TimeDelta transform_duration = - std::max(save_directive_->duration(), kMinimumAnimationDuration); + base::TimeDelta transform_duration = kDefaultAnimationDuration; std::unique_ptr<gfx::KeyframedTransformAnimationCurve> transform_curve( gfx::KeyframedTransformAnimationCurve::Create());
diff --git a/components/viz/service/transitions/surface_animation_manager_unittest.cc b/components/viz/service/transitions/surface_animation_manager_unittest.cc index 88d7234..16496c3 100644 --- a/components/viz/service/transitions/surface_animation_manager_unittest.cc +++ b/components/viz/service/transitions/surface_animation_manager_unittest.cc
@@ -24,13 +24,11 @@ std::vector<CompositorFrameTransitionDirective> CreateSaveDirectiveAsVector( uint32_t sequence_id, - base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100), CompositorFrameTransitionDirective::Effect effect = CompositorFrameTransitionDirective::Effect::kCoverDown) { std::vector<CompositorFrameTransitionDirective> result; result.emplace_back(sequence_id, - CompositorFrameTransitionDirective::Type::kSave, effect, - duration); + CompositorFrameTransitionDirective::Type::kSave, effect); return result; } @@ -221,7 +219,7 @@ EXPECT_TRUE(manager.NeedsBeginFrame()); manager.NotifyFrameAdvanced( - AdvanceTime(base::TimeDelta::FromMilliseconds(50))); + AdvanceTime(base::TimeDelta::FromMilliseconds(500))); // We should be at the done state, but still need a frame. EXPECT_TRUE(manager.NeedsBeginFrame()); @@ -284,7 +282,7 @@ EXPECT_TRUE(manager.NeedsBeginFrame()); manager.NotifyFrameAdvanced( - AdvanceTime(base::TimeDelta::FromMilliseconds(100))); + AdvanceTime(base::TimeDelta::FromMilliseconds(500))); // We're at the done state now. EXPECT_TRUE(manager.NeedsBeginFrame()); @@ -316,9 +314,7 @@ uint32_t sequence_id = 1; for (auto effect : effects) { manager.ProcessTransitionDirectives( - CreateSaveDirectiveAsVector( - sequence_id++, base::TimeDelta::FromMilliseconds(500), effect), - storage()); + CreateSaveDirectiveAsVector(sequence_id++, effect), storage()); storage()->CompleteForTesting(); @@ -349,33 +345,4 @@ } } -TEST_F(SurfaceAnimationManagerTest, MinimumDuration) { - TestSurfaceAnimationManager manager; - manager.SetDirectiveFinishedCallback(base::DoNothing()); - EXPECT_FALSE(manager.NeedsBeginFrame()); - - // This animation is too short. - manager.ProcessTransitionDirectives( - CreateSaveDirectiveAsVector(1, base::TimeDelta::FromMilliseconds(1)), - storage()); - - storage()->CompleteForTesting(); - - manager.ProcessTransitionDirectives(CreateAnimateDirectiveAsVector(2), - storage()); - - // Tick curves to set start time. - manager.NotifyFrameAdvanced(AdvanceTime(base::TimeDelta())); - - EXPECT_TRUE(manager.NeedsBeginFrame()); - - manager.NotifyFrameAdvanced( - AdvanceTime(base::TimeDelta::FromMilliseconds(10))); - - // Despite ticking beyond the stated duration of the effect, 10ms is still - // way too fast for a transition; we expect to still be transitioning at - // this point. - EXPECT_TRUE(manager.NeedsBeginFrame()); -} - } // namespace viz
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index c235226..db93a05 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -860,15 +860,10 @@ params.sandbox_info)) return TerminateForFatalInitializationError(); #elif defined(OS_MAC) - // Only the GPU process still runs the V1 sandbox. - bool v2_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch( - sandbox::switches::kSeatbeltClientName); - - if (!v2_enabled && process_type == switches::kGpuProcess) { - if (!InitializeSandbox()) { - return TerminateForFatalInitializationError(); - } - } else if (v2_enabled) { + if (!sandbox::policy::IsUnsandboxedSandboxType( + sandbox::policy::SandboxTypeFromCommandLine(command_line))) { + // Verify that the sandbox was initialized prior to ContentMain using the + // SeatbeltExecServer. CHECK(sandbox::Seatbelt::IsSandboxed()); } #endif
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 4957066..e7505c68 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -916,6 +916,8 @@ "histogram_synchronizer.h", "histograms_internals_ui.cc", "histograms_internals_ui.h", + "histograms_monitor.cc", + "histograms_monitor.h", "idle/idle_manager_impl.cc", "idle/idle_manager_impl.h", "idle/idle_monitor.cc",
diff --git a/content/browser/appcache/appcache_quota_client.cc b/content/browser/appcache/appcache_quota_client.cc index baab9a6f..e207e1c 100644 --- a/content/browser/appcache/appcache_quota_client.cc +++ b/content/browser/appcache/appcache_quota_client.cc
@@ -11,7 +11,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/task/post_task.h" #include "content/browser/appcache/appcache_service_impl.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -41,8 +40,8 @@ void RunDeleteOnIO(const base::Location& from_here, net::CompletionRepeatingCallback callback, int result) { - base::PostTask(from_here, {BrowserThread::IO}, - base::BindOnce(std::move(callback), result)); + GetIOThreadTaskRunner({})->PostTask( + from_here, base::BindOnce(std::move(callback), result)); } } // namespace
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 5a0eb85..8122d8a 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -6854,16 +6854,8 @@ // resets the reasing back to have alpha=0 and navigates back to the a-page and // catpures 3 more events and verifies that all events on the a-page have // alpha=1. -// Flaky on Mac and Linux ASAN/TSAN. https://crbug.com/1029238 -#if defined(OS_MAC) || \ - ((defined(OS_LINUX) || defined(OS_CHROMEOS)) && \ - (defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER))) -#define MAYBE_SensorPausedWhileCached DISABLED_SensorPausedWhileCached -#else -#define MAYBE_SensorPausedWhileCached SensorPausedWhileCached -#endif IN_PROC_BROWSER_TEST_F(SensorBackForwardCacheBrowserTest, - MAYBE_SensorPausedWhileCached) { + SensorPausedWhileCached) { ASSERT_TRUE(CreateHttpsServer()->Start()); GURL url_a(https_server()->GetURL("a.com", "/title1.html")); GURL url_b(https_server()->GetURL("b.com", "/title1.html"));
diff --git a/content/browser/background_fetch/background_fetch_test_data_manager.cc b/content/browser/background_fetch/background_fetch_test_data_manager.cc index b958c3b..41d8462 100644 --- a/content/browser/background_fetch/background_fetch_test_data_manager.cc +++ b/content/browser/background_fetch/background_fetch_test_data_manager.cc
@@ -7,11 +7,11 @@ #include <utility> #include "base/run_loop.h" -#include "base/task/post_task.h" #include "components/services/storage/public/mojom/quota_client.mojom.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "storage/browser/blob/blob_storage_context.h" @@ -101,8 +101,8 @@ mojo::PendingRemote<storage::mojom::BlobStorageContext> remote; base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&ChromeBlobStorageContext::BindMojoContext, blob_storage_context_, remote.InitWithNewPipeAndPassReceiver()),
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 63ed088..2744432 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -178,10 +178,6 @@ #include "third_party/blink/public/mojom/input/text_input_host.mojom.h" #endif -#if defined(OS_MAC) && defined(ARCH_CPU_ARM_FAMILY) -#include "media/mojo/mojom/cdm_infobar_service.mojom.h" -#endif - namespace content { namespace internal { @@ -937,11 +933,6 @@ map->Add<blink::mojom::RawClipboardHost>( base::BindRepeating(&RawClipboardHostImpl::Create)); -#if defined(OS_MAC) && defined(ARCH_CPU_ARM_FAMILY) - map->Add<media::mojom::CdmInfobarService>(base::BindRepeating( - &EmptyBinderForFrame<media::mojom::CdmInfobarService>)); -#endif - GetContentClient()->browser()->RegisterBrowserInterfaceBindersForFrame(host, map); }
diff --git a/content/browser/child_process_launcher_helper_mac.cc b/content/browser/child_process_launcher_helper_mac.cc index fb0de89..ba0deaa5 100644 --- a/content/browser/child_process_launcher_helper_mac.cc +++ b/content/browser/child_process_launcher_helper_mac.cc
@@ -7,7 +7,6 @@ #include "base/path_service.h" #include "base/posix/global_descriptors.h" #include "base/strings/stringprintf.h" -#include "build/build_config.h" #include "content/browser/child_process_launcher.h" #include "content/browser/child_process_launcher_helper.h" #include "content/browser/child_process_launcher_helper_posix.h" @@ -63,10 +62,6 @@ options->mach_ports_for_rendezvous.insert(std::make_pair( 'mojo', base::MachRendezvousPort(endpoint.TakeMachReceiveRight()))); -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - options->launch_x86_64 = delegate_->LaunchX86_64(); -#endif // OS_MAC && ARCH_CPU_ARM64 - options->environment = delegate_->GetEnvironment(); options->disclaim_responsibility = delegate_->DisclaimResponsibility();
diff --git a/content/browser/histograms_internals_ui.cc b/content/browser/histograms_internals_ui.cc index 74c76bc9..ba8f123 100644 --- a/content/browser/histograms_internals_ui.cc +++ b/content/browser/histograms_internals_ui.cc
@@ -16,6 +16,7 @@ #include "base/metrics/statistics_recorder.h" #include "base/values.h" #include "content/browser/histogram_synchronizer.h" +#include "content/browser/histograms_monitor.h" #include "content/grit/content_resources.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" @@ -30,6 +31,14 @@ const char kHistogramsUIJs[] = "histograms_internals.js"; const char kHistogramsUIRequestHistograms[] = "requestHistograms"; +const char kHistogramsUIStartMonitoring[] = "startMonitoring"; +const char kHistogramsUIFetchDiff[] = "fetchDiff"; + +// Stores the information received from Javascript side. +struct JsParams { + std::string callback_id; + std::string query; +}; WebUIDataSource* CreateHistogramsHTMLSource() { WebUIDataSource* source = WebUIDataSource::Create(kChromeUIHistogramHost); @@ -52,7 +61,13 @@ private: void HandleRequestHistograms(const base::ListValue* args); + void HandleStartMoninoring(const base::ListValue* args); + void HandleFetchDiff(const base::ListValue* args); + // Calls AllowJavascript() and unpacks the passed params. + JsParams AllowJavascriptAndUnpackParams(const base::ListValue& args); + + HistogramsMonitor histogram_monitor_; DISALLOW_COPY_AND_ASSIGN(HistogramsMessageHandler); }; @@ -60,27 +75,45 @@ HistogramsMessageHandler::~HistogramsMessageHandler() {} +JsParams HistogramsMessageHandler::AllowJavascriptAndUnpackParams( + const base::ListValue& args) { + AllowJavascript(); + JsParams params; + args.GetString(0, ¶ms.callback_id); + args.GetString(1, ¶ms.query); + return params; +} + void HistogramsMessageHandler::HandleRequestHistograms( const base::ListValue* args) { base::StatisticsRecorder::ImportProvidedHistograms(); HistogramSynchronizer::FetchHistograms(); - - AllowJavascript(); - std::string callback_id; - args->GetString(0, &callback_id); - std::string query; - args->GetString(1, &query); - + JsParams params = AllowJavascriptAndUnpackParams(*args); base::ListValue histograms_list; for (base::HistogramBase* histogram : base::StatisticsRecorder::Sort(base::StatisticsRecorder::WithName( - base::StatisticsRecorder::GetHistograms(), query))) { + base::StatisticsRecorder::GetHistograms(), params.query))) { base::DictionaryValue histogram_dict = histogram->ToGraphDict(); if (!histogram_dict.empty()) histograms_list.Append(std::move(histogram_dict)); } - ResolveJavascriptCallback(base::Value(callback_id), + ResolveJavascriptCallback(base::Value(params.callback_id), + std::move(histograms_list)); +} + +void HistogramsMessageHandler::HandleStartMoninoring( + const base::ListValue* args) { + JsParams params = AllowJavascriptAndUnpackParams(*args); + histogram_monitor_.StartMonitoring(params.query); + ResolveJavascriptCallback(base::Value(params.callback_id), + base::Value("Success")); +} + +void HistogramsMessageHandler::HandleFetchDiff(const base::ListValue* args) { + JsParams params = AllowJavascriptAndUnpackParams(*args); + base::ListValue histograms_list = histogram_monitor_.GetDiff(); + ResolveJavascriptCallback(base::Value(params.callback_id), std::move(histograms_list)); } @@ -93,6 +126,16 @@ kHistogramsUIRequestHistograms, base::BindRepeating(&HistogramsMessageHandler::HandleRequestHistograms, base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + kHistogramsUIStartMonitoring, + base::BindRepeating(&HistogramsMessageHandler::HandleStartMoninoring, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + kHistogramsUIFetchDiff, + base::BindRepeating(&HistogramsMessageHandler::HandleFetchDiff, + base::Unretained(this))); } } // namespace
diff --git a/content/browser/histograms_monitor.cc b/content/browser/histograms_monitor.cc new file mode 100644 index 0000000..96cb53d --- /dev/null +++ b/content/browser/histograms_monitor.cc
@@ -0,0 +1,62 @@ +// 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 "content/browser/histograms_monitor.h" + +#include "base/macros.h" +#include "base/metrics/histogram_samples.h" +#include "base/metrics/statistics_recorder.h" +#include "content/browser/histogram_synchronizer.h" + +namespace content { + +HistogramsMonitor::HistogramsMonitor() = default; + +HistogramsMonitor::~HistogramsMonitor() = default; + +void HistogramsMonitor::StartMonitoring(const std::string& query) { + query_ = query; + FetchHistograms(); + histograms_snapshot_.clear(); + // Save a snapshot of all current histograms that will be used as a baseline. + for (const auto* const histogram : base::StatisticsRecorder::WithName( + base::StatisticsRecorder::GetHistograms(), query_)) { + histograms_snapshot_[histogram->histogram_name()] = + histogram->SnapshotSamples(); + } +} + +base::ListValue HistogramsMonitor::GetDiff() { + FetchHistograms(); + base::StatisticsRecorder::Histograms histograms = + base::StatisticsRecorder::Sort(base::StatisticsRecorder::WithName( + base::StatisticsRecorder::GetHistograms(), query_)); + return GetDiffInternal(histograms); +} + +void HistogramsMonitor::FetchHistograms() { + base::StatisticsRecorder::ImportProvidedHistograms(); + HistogramSynchronizer::FetchHistograms(); +} + +base::ListValue HistogramsMonitor::GetDiffInternal( + const base::StatisticsRecorder::Histograms& histograms) { + base::ListValue histograms_list; + for (const base::HistogramBase* const histogram : histograms) { + std::unique_ptr<base::HistogramSamples> snapshot = + histogram->SnapshotSamples(); + auto it = histograms_snapshot_.find(histogram->histogram_name()); + if (it != histograms_snapshot_.end()) { + snapshot->Subtract(*it->second.get()); + } + if (snapshot->TotalCount() > 0) { + base::DictionaryValue histogram_dict = snapshot->ToGraphDict( + histogram->histogram_name(), histogram->flags()); + histograms_list.Append(std::move(histogram_dict)); + } + } + return histograms_list; +} + +} // namespace content
diff --git a/content/browser/histograms_monitor.h b/content/browser/histograms_monitor.h new file mode 100644 index 0000000..022cd1e --- /dev/null +++ b/content/browser/histograms_monitor.h
@@ -0,0 +1,53 @@ +// 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 CONTENT_BROWSER_HISTOGRAMS_MONITOR_H_ +#define CONTENT_BROWSER_HISTOGRAMS_MONITOR_H_ + +#include <map> + +#include "base/metrics/histogram_samples.h" +#include "base/metrics/statistics_recorder.h" +#include "content/common/content_export.h" + +namespace content { + +// This class handles the monitoring feature of chrome://histograms page, +// which allows the page to be updated with histograms logged since +// the monitoring started. +class CONTENT_EXPORT HistogramsMonitor { + public: + HistogramsMonitor(); + ~HistogramsMonitor(); + + HistogramsMonitor(const HistogramsMonitor&) = delete; + HistogramsMonitor& operator=(const HistogramsMonitor&) = delete; + + // Fetches and records a snapshot of the current histograms, + // as the baseline to compare against in subsequent calls to GetDiff(). + void StartMonitoring(const std::string& query); + + // Gets the histogram diffs between the current histograms and the snapshot + // recorded in StartMonitoring(). + base::ListValue GetDiff(); + + private: + // Imports histograms from the StatisticsRecorder. + // Also contacts all processes, and gets them to upload to the browser any/all + // changes to histograms. + void FetchHistograms(); + + // Gets the difference between the histograms argument and the stored snapshot + // recorded in StartMonitoring(). + base::ListValue GetDiffInternal( + const base::StatisticsRecorder::Histograms& histograms); + + std::string query_; + std::map<std::string, std::unique_ptr<base::HistogramSamples>> + histograms_snapshot_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_HISTOGRAMS_MONITOR_H_
diff --git a/content/browser/histograms_monitor_unittest.cc b/content/browser/histograms_monitor_unittest.cc new file mode 100644 index 0000000..3c4600f --- /dev/null +++ b/content/browser/histograms_monitor_unittest.cc
@@ -0,0 +1,72 @@ +// 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 "content/browser/histograms_monitor.h" + +#include "base/metrics/histogram_macros.h" +#include "base/metrics/statistics_recorder.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +class HistogramsMonitorTest : public testing::Test { + public: + HistogramsMonitorTest() + : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {} + content::BrowserTaskEnvironment task_environment_; +}; + +TEST_F(HistogramsMonitorTest, StartMonitoringThenGetDiff) { + base::StatisticsRecorder::ForgetHistogramForTesting("MonitorHistogram1"); + base::StatisticsRecorder::ForgetHistogramForTesting("MonitorHistogram2"); + base::HistogramBase* histogram1 = base::Histogram::FactoryGet( + "MonitorHistogram1", 1, 1000, 10, base::HistogramBase::kNoFlags); + histogram1->Add(30); + HistogramsMonitor monitor; + monitor.StartMonitoring(""); + + // Get diff immediately should return nothing. + base::ListValue diff = monitor.GetDiff(); + ASSERT_EQ(diff.GetList().size(), 0ull); + + // Add more data to histogram. + histogram1->Add(30); + histogram1->Add(40); + + diff = monitor.GetDiff(); + ASSERT_EQ(diff.GetList().size(), 1ull); + std::string* header1 = diff.GetList()[0].FindStringKey("header"); + EXPECT_EQ(*header1, + "Histogram: MonitorHistogram1 recorded 2 samples, mean = 35.0"); + + // Add another histogram + base::HistogramBase* histogram2 = base::Histogram::FactoryGet( + "MonitorHistogram2", 1, 1000, 10, base::HistogramBase::kNoFlags); + histogram2->Add(50); + diff = monitor.GetDiff(); + ASSERT_EQ(diff.GetList().size(), 2ull); + std::string* header2 = diff.GetList()[1].FindStringKey("header"); + EXPECT_EQ(*header2, + "Histogram: MonitorHistogram2 recorded 1 samples, mean = 50.0"); +} + +TEST_F(HistogramsMonitorTest, StartMonitoringWithQueryThenGetDiff) { + base::StatisticsRecorder::ForgetHistogramForTesting("MonitorHistogram1"); + base::StatisticsRecorder::ForgetHistogramForTesting("MonitorHistogram2"); + base::HistogramBase* histogram1 = base::Histogram::FactoryGet( + "MonitorHistogram1", 1, 1000, 10, base::HistogramBase::kNoFlags); + histogram1->Add(30); + HistogramsMonitor monitor; + monitor.StartMonitoring("MonitorHistogram1"); + + base::HistogramBase* histogram2 = base::Histogram::FactoryGet( + "MonitorHistogram2", 1, 1000, 10, base::HistogramBase::kNoFlags); + histogram2->Add(50); + base::ListValue diff = monitor.GetDiff(); + ASSERT_EQ(diff.GetList().size(), 0ull); +} + +} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 61b1c3c..4bafa78 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -997,8 +997,8 @@ std::string(s_corrupt_db_test_prefix) + "corrupted_open_db_recovery.html"; SimpleTest(embedded_test_server()->GetURL(test_file)); } -#endif +// Only instantiate on platforms that run the parameterized test. INSTANTIATE_TEST_SUITE_P(IndexedDBBrowserTestInstantiation, IndexedDBBrowserTest, ::testing::Values("failGetBlobJournal", @@ -1007,6 +1007,7 @@ "iterate", "failTransactionCommit", "clearObjectStore")); +#endif // !defined(OS_WIN) IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteCompactsBackingStore) { const GURL kTestUrl = GetTestUrl("indexeddb", "delete_compact.html");
diff --git a/content/browser/media/capture/mouse_cursor_overlay_controller.h b/content/browser/media/capture/mouse_cursor_overlay_controller.h index 9c85000b..b4db367 100644 --- a/content/browser/media/capture/mouse_cursor_overlay_controller.h +++ b/content/browser/media/capture/mouse_cursor_overlay_controller.h
@@ -42,6 +42,16 @@ // Sets a new target view to monitor for mouse cursor updates. void SetTargetView(gfx::NativeView view); + // If the target view is not a gfx::NativeView (which is the case when + // capturing a NSWindow on macOS), this function may be used to set the size + // of the target. This function will only have an effect if SetTargetView has + // not been called (it doesn't make sense to call both functions). The units + // for |target_size| are different on different platforms (DIPs on macOS, + // pixels on all other platforms). + void SetTargetSize(const gfx::Size& target_size) { + target_size_ = target_size; + } + // Takes ownership of and starts controlling the given |overlay|, invoking its // methods (and destruction) via the given |task_runner|. void Start(std::unique_ptr<Overlay> overlay, @@ -51,9 +61,16 @@ // destruction. void Stop(); - // Returns true if the user has recently interacted with the view. + // Returns true if the user has recently interacted with the target (by + // moving or clicking the mouse). bool IsUserInteractingWithView() const; + // Called from platform-specific code to report on mouse events within the + // captured view. The units for |location| depend on the platform (DIPs on + // macOS and pixels on other platforms). + void OnMouseMoved(const gfx::PointF& location); + void OnMouseClicked(const gfx::PointF& location); + // Returns a weak pointer. base::WeakPtr<MouseCursorOverlayController> GetWeakPtr(); @@ -70,11 +87,6 @@ kRecentlyMovedOrClicked, // Sufficient mouse activity present. }; - // Called from platform-specific code to report on mouse events within the - // captured view. - void OnMouseMoved(const gfx::PointF& location); - void OnMouseClicked(const gfx::PointF& location); - // Called by the |mouse_activity_ended_timer_| once no mouse events have // occurred for kIdleTimeout. Also, called by platform-specific code when // changing the target view. @@ -141,6 +153,9 @@ // depending on the cursor's hotspot. gfx::RectF bounds_; + // The target's size, if set explicitly by SetTargetSize. + gfx::Size target_size_; + // Everything except the constructor and IsUserInteractingWithView() must be // called on the UI BrowserThread. SEQUENCE_CHECKER(ui_sequence_checker_);
diff --git a/content/browser/media/capture/mouse_cursor_overlay_controller_mac.mm b/content/browser/media/capture/mouse_cursor_overlay_controller_mac.mm index af4d27f4..3fb0dee0 100644 --- a/content/browser/media/capture/mouse_cursor_overlay_controller_mac.mm +++ b/content/browser/media/capture/mouse_cursor_overlay_controller_mac.mm
@@ -160,19 +160,26 @@ const gfx::PointF& location_aura) const { DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); + gfx::Size target_size; if (NSView* view = Observer::GetTargetView(observer_)) { const NSRect view_bounds = [view bounds]; - if (!NSIsEmptyRect(view_bounds)) { - // The documentation on NSCursor reference states that the hot spot is in - // flipped coordinates which, from the perspective of the Aura coordinate - // system, means it's not flipped. - const NSPoint hotspot = [cursor hotSpot]; - const NSSize size = [[cursor image] size]; - return gfx::ScaleRect( - gfx::RectF(location_aura.x() - hotspot.x, - location_aura.y() - hotspot.y, size.width, size.height), - 1.0 / NSWidth(view_bounds), 1.0 / NSHeight(view_bounds)); - } + target_size = gfx::Size(NSWidth(view_bounds), NSHeight(view_bounds)); + } else { + // The target for capture can be a views::Widget, which is an NSWindow, + // not a NSView. This path is used in that case. + target_size = target_size_; + } + + if (target_size.GetArea()) { + // The documentation on NSCursor reference states that the hot spot is in + // flipped coordinates which, from the perspective of the Aura coordinate + // system, means it's not flipped. + const NSPoint hotspot = [cursor hotSpot]; + const NSSize size = [[cursor image] size]; + return gfx::ScaleRect( + gfx::RectF(location_aura.x() - hotspot.x, location_aura.y() - hotspot.y, + size.width, size.height), + 1.0 / target_size.width(), 1.0 / target_size.height()); } return gfx::RectF();
diff --git a/content/browser/media/capture/views_widget_video_capture_device_mac.cc b/content/browser/media/capture/views_widget_video_capture_device_mac.cc index bee6cbb..9146a4e5 100644 --- a/content/browser/media/capture/views_widget_video_capture_device_mac.cc +++ b/content/browser/media/capture/views_widget_video_capture_device_mac.cc
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/threading/thread_task_runner_handle.h" #include "components/remote_cocoa/browser/scoped_cg_window_id.h" +#include "content/browser/media/capture/mouse_cursor_overlay_controller.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/desktop_media_id.h" @@ -19,10 +20,12 @@ : public remote_cocoa::ScopedCGWindowID::Observer { public: UIThreadDelegate(uint32_t cg_window_id, - const base::WeakPtr<FrameSinkVideoCaptureDevice> device) + const base::WeakPtr<FrameSinkVideoCaptureDevice> device, + MouseCursorOverlayController* cursor_controller) : cg_window_id_(cg_window_id), device_task_runner_(base::ThreadTaskRunnerHandle::Get()), - device_(device) { + device_(device), + cursor_controller_(cursor_controller) { // Note that the use of base::Unretained below is safe, because // |this| is destroyed by a task posted to the same thread task runner. GetUIThreadTaskRunner({})->PostTask( @@ -76,6 +79,12 @@ base::BindOnce(&FrameSinkVideoCaptureDevice::OnTargetPermanentlyLost, device_)); } + void OnScopedCGWindowIDMouseMoved(uint32_t cg_window_id, + const gfx::PointF& location_in_window, + const gfx::Size& window_size) override { + cursor_controller_->SetTargetSize(window_size); + cursor_controller_->OnMouseMoved(location_in_window); + } const uint32_t cg_window_id_; const scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_; @@ -87,13 +96,19 @@ // |device_| may only be dereferenced by tasks posted to // |device_task_runner_|. base::WeakPtr<FrameSinkVideoCaptureDevice> device_; + + // Owned by FrameSinkVideoCaptureDevice. This will be valid for the life of + // UIThreadDelegate because the UIThreadDelegate deleter task will be posted + // to the UI thread before the MouseCursorOverlayController deleter task. + // See similar behavior in WebContentsVideoCaptureDevice::FrameTracker. + MouseCursorOverlayController* const cursor_controller_; }; ViewsWidgetVideoCaptureDeviceMac::ViewsWidgetVideoCaptureDeviceMac( const DesktopMediaID& source_id) : weak_factory_(this) { ui_thread_delegate_ = std::make_unique<UIThreadDelegate>( - source_id.id, weak_factory_.GetWeakPtr()); + source_id.id, weak_factory_.GetWeakPtr(), cursor_controller()); } ViewsWidgetVideoCaptureDeviceMac::~ViewsWidgetVideoCaptureDeviceMac() {
diff --git a/content/browser/media/media_interface_proxy.cc b/content/browser/media/media_interface_proxy.cc index a570a90..38fa3243 100644 --- a/content/browser/media/media_interface_proxy.cc +++ b/content/browser/media/media_interface_proxy.cc
@@ -197,11 +197,6 @@ if (!remote) { ServiceProcessHost::Options options; options.WithDisplayName(display_name); -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - if (cdm_info.launch_x86_64) { - options.WithChildFlags(ChildProcessHost::CHILD_LAUNCH_X86_64); - } -#endif // OS_MAC && ARCH_CPU_ARM64 ServiceProcessHost::Launch(remote.BindNewPipeAndPassReceiver(), options.Pass()); remote.set_disconnect_handler(base::BindOnce(&EraseCdmService, key));
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc index 21954cc..f2e0303 100644 --- a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
@@ -76,8 +76,8 @@ render_process_id, render_frame_id, media_stream_manager), std::move(receiver)); - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce( + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( [](int render_process_id, int render_frame_id) { RenderFrameHost* render_frame_host = RenderFrameHost::FromID(render_process_id,
diff --git a/content/browser/renderer_host/render_frame_proxy_host.cc b/content/browser/renderer_host/render_frame_proxy_host.cc index cdf53d64..54fa3b7 100644 --- a/content/browser/renderer_host/render_frame_proxy_host.cc +++ b/content/browser/renderer_host/render_frame_proxy_host.cc
@@ -337,12 +337,7 @@ // receivers by resetting them before binding. // TODO(dcheng): Maybe there should be an equivalent to RenderFrameHostImpl's // InvalidateMojoConnection()? - if (interface_name == mojom::RenderFrameProxyHost::Name_) { - frame_proxy_host_associated_receiver_.reset(); - frame_proxy_host_associated_receiver_.Bind( - mojo::PendingAssociatedReceiver<mojom::RenderFrameProxyHost>( - std::move(handle))); - } else if (interface_name == blink::mojom::RemoteFrameHost::Name_) { + if (interface_name == blink::mojom::RemoteFrameHost::Name_) { remote_frame_host_receiver_.reset(); remote_frame_host_receiver_.Bind( mojo::PendingAssociatedReceiver<blink::mojom::RemoteFrameHost>( @@ -378,11 +373,6 @@ } void RenderFrameProxyHost::SetRenderFrameProxyCreated(bool created) { - if (!created) { - // If the renderer process has gone away, created can be false. In that - // case, invalidate the mojo connection. - frame_proxy_host_associated_receiver_.reset(); - } render_frame_proxy_created_ = created; } @@ -400,13 +390,6 @@ return remote_main_frame_; } -const mojo::AssociatedRemote<content::mojom::RenderFrameProxy>& -RenderFrameProxyHost::GetAssociatedRenderFrameProxy() { - if (!render_frame_proxy_) - GetRemoteAssociatedInterfaces()->GetInterface(&render_frame_proxy_); - return render_frame_proxy_; -} - void RenderFrameProxyHost::SetInheritedEffectiveTouchAction( cc::TouchAction touch_action) { cross_process_frame_connector_->OnSetInheritedEffectiveTouchAction(
diff --git a/content/browser/renderer_host/render_frame_proxy_host.h b/content/browser/renderer_host/render_frame_proxy_host.h index b973ae97..cd6c90f 100644 --- a/content/browser/renderer_host/render_frame_proxy_host.h +++ b/content/browser/renderer_host/render_frame_proxy_host.h
@@ -13,7 +13,6 @@ #include "base/macros.h" #include "content/browser/site_instance_impl.h" #include "content/common/frame.mojom.h" -#include "content/common/frame_proxy.mojom.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" #include "mojo/public/cpp/bindings/associated_receiver.h" @@ -69,7 +68,6 @@ class CONTENT_EXPORT RenderFrameProxyHost : public IPC::Listener, public IPC::Sender, - public mojom::RenderFrameProxyHost, public blink::mojom::RemoteFrameHost, public blink::mojom::RemoteMainFrameHost { public: @@ -202,6 +200,7 @@ override; void SynchronizeVisualProperties( const blink::FrameVisualProperties& frame_visual_properties) override; + void OpenURL(blink::mojom::OpenURLParamsPtr params) override; // blink::mojom::RemoteMainFrameHost overrides: void FocusPage() override; @@ -212,13 +211,6 @@ override; void RouteCloseEvent() override; - // mojom::RenderFrameProxyHost: - void OpenURL(blink::mojom::OpenURLParamsPtr params) override; - - // Returns associated remote for the content::mojom::RenderFrameProxy Mojo - // interface. - const mojo::AssociatedRemote<mojom::RenderFrameProxy>& - GetAssociatedRenderFrameProxy(); // Requests a viz::LocalSurfaceId to enable auto-resize mode from the parent // renderer. void EnableAutoResize(const gfx::Size& min_size, const gfx::Size& max_size); @@ -235,8 +227,7 @@ private: // These interceptor need access to frame_host_receiver_for_testing(). - friend class RouteMessageEventInterceptor; - friend class OpenURLInterceptor; + friend class RemoteFrameHostInterceptor; friend class UpdateViewportIntersectionMessageFilter; friend class SynchronizeVisualPropertiesInterceptor; @@ -257,12 +248,6 @@ return remote_frame_host_receiver_; } - // Needed for tests to be able to swap the implementation and intercept calls. - mojo::AssociatedReceiver<mojom::RenderFrameProxyHost>& - frame_proxy_host_receiver_for_testing() { - return frame_proxy_host_associated_receiver_; - } - // This RenderFrameProxyHost's routing id. int routing_id_; @@ -299,10 +284,6 @@ std::unique_ptr<blink::AssociatedInterfaceProvider> remote_associated_interfaces_; - // Mojo receiver to this RenderFrameProxyHost. - mojo::AssociatedReceiver<mojom::RenderFrameProxyHost> - frame_proxy_host_associated_receiver_{this}; - // Holder of Mojo connection with the Frame service in Blink. mojo::AssociatedRemote<blink::mojom::RemoteFrame> remote_frame_; @@ -310,9 +291,6 @@ // will be valid when the frame is the active main frame. mojo::AssociatedRemote<blink::mojom::RemoteMainFrame> remote_main_frame_; - // Holder of Mojo connection with the content::mojom::RenderFrameProxy. - mojo::AssociatedRemote<mojom::RenderFrameProxy> render_frame_proxy_; - mojo::AssociatedReceiver<blink::mojom::RemoteFrameHost> remote_frame_host_receiver_{this};
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index a989d1c..4301f99 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2437,22 +2437,15 @@ // Show the virtual keyboard if needed. if (state && state->type != ui::TEXT_INPUT_TYPE_NONE && state->mode != ui::TEXT_INPUT_MODE_NONE) { - bool show_virtual_keyboard = true; -#if defined(OS_FUCHSIA) - show_virtual_keyboard = - GetLastPointerType() == ui::EventPointerType::kTouch; -#endif - #if !defined(OS_WIN) if (state->show_ime_if_needed && - GetInputMethod()->GetTextInputClient() == this && - show_virtual_keyboard) { + GetInputMethod()->GetTextInputClient() == this) { GetInputMethod()->ShowVirtualKeyboardIfEnabled(); } // TODO(crbug.com/1031786): Remove this once TSF fix for input pane policy // is serviced #elif defined(OS_WIN) - if (GetInputMethod() && show_virtual_keyboard) { + if (GetInputMethod()) { if (!virtual_keyboard_controller_win_) { virtual_keyboard_controller_win_.reset( new VirtualKeyboardControllerWin(this, GetInputMethod()));
diff --git a/content/browser/resources/histograms/histograms_internals.html b/content/browser/resources/histograms/histograms_internals.html index e725fb7..3429d70 100644 --- a/content/browser/resources/histograms/histograms_internals.html +++ b/content/browser/resources/histograms/histograms_internals.html
@@ -9,9 +9,17 @@ <title>Histograms</title> </head> <h1>Histograms</h1> -<p>Stats accumulated from browser startup to previous page load; reload to get stats as of this page load. -</p> -<button id="refresh">Refresh</button> +<div id="accumulating_section"> + <button id="enable_monitoring">Switch to Monitoring Mode</button> + <p>Stats accumulated from browser startup to previous page load; + reload to get stats as of this page load.</p> + <button id="refresh">Refresh</button> +</div> +<div id="monitoring_section" style="display: none"> + <button id="disable_monitoring">Switch to Histogram Mode</button> + <p>The page will show the difference in histogram data since you switched to + Monitoring mode. The page will automatically refresh every 1 second.</p> +</div> <div id="histograms"></div> <template id="histogram-template"><pre><h4></h4><p></p></pre><br><hr><br></template> </html>
diff --git a/content/browser/resources/histograms/histograms_internals.js b/content/browser/resources/histograms/histograms_internals.js index 5d4786a..79fc79d7 100644 --- a/content/browser/resources/histograms/histograms_internals.js +++ b/content/browser/resources/histograms/histograms_internals.js
@@ -5,15 +5,70 @@ import {sendWithPromise} from 'chrome://resources/js/cr.m.js'; import {$} from 'chrome://resources/js/util.m.js'; +// Timer for automatic update in monitoring mode. +let fetchDiffScheduler = null; + /** * Initiates the request for histograms. */ function requestHistograms() { - let query = ''; + sendWithPromise('requestHistograms', getQuery()).then(addHistograms); +} + +/** + * Starts monitoring histograms. + * This will get a histogram snapshot as the base to be diffed against. + */ +function startMonitoring() { + sendWithPromise('startMonitoring', getQuery()).then(fetchDiff); +} + +/** + * Schedules the fetching of histogram diff (after 1000ms) and rendering it. + * This will also recursively call the next fetchDiff() to periodically updtate + * the page. + */ +function fetchDiff() { + fetchDiffScheduler = setTimeout(function() { + sendWithPromise('fetchDiff', getQuery()) + .then(addHistograms) + .then(fetchDiff); + }, 1000); +} + +/** + * Gets the query string from the URL. + * For example, if the URL is chrome://histograms/abc, then query is "abc". + */ +function getQuery() { if (document.location.pathname) { - query = document.location.pathname.substring(1); + return document.location.pathname.substring(1); } - sendWithPromise('requestHistograms', query).then(addHistograms); + return ''; +} + +/** + * Callback function when users switch to Monitoring mode. + */ +function enableMonitoring() { + $('accumulating_section').style.display = 'none'; + $('monitoring_section').style.display = 'block'; + $('histograms').innerHTML = trustedTypes.emptyHTML; + startMonitoring(); +} + +/** + * Callback function when users switch away from Monitoring mode. + */ +function disableMonitoring() { + if (fetchDiffScheduler) { + clearTimeout(fetchDiffScheduler); + fetchDiffScheduler = null; + } + $('accumulating_section').style.display = 'block'; + $('monitoring_section').style.display = 'none'; + $('histograms').innerHTML = trustedTypes.emptyHTML; + requestHistograms(); } /** @@ -40,6 +95,7 @@ */ document.addEventListener('DOMContentLoaded', function() { $('refresh').onclick = requestHistograms; - + $('enable_monitoring').onclick = enableMonitoring; + $('disable_monitoring').onclick = disableMonitoring; requestHistograms(); });
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index 01fd9dd..1fd9f1b 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -28,7 +28,6 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame.mojom.h" #include "content/common/frame_messages.h" -#include "content/common/frame_proxy.mojom-test-utils.h" #include "content/common/render_message_filter.mojom.h" #include "content/public/browser/blob_handle.h" #include "content/public/browser/browser_context.h" @@ -801,10 +800,10 @@ child->current_frame_host()->GetLastCommittedURL()); } -class RouteMessageEventInterceptor +class RemoteFrameHostInterceptor : public blink::mojom::RemoteFrameHostInterceptorForTesting { public: - explicit RouteMessageEventInterceptor( + explicit RemoteFrameHostInterceptor( RenderFrameProxyHost* render_frame_proxy_host, const std::u16string& evil_origin) : render_frame_proxy_host_(render_frame_proxy_host), @@ -829,9 +828,19 @@ std::move(target_origin), std::move(message)); } + void OpenURL(blink::mojom::OpenURLParamsPtr params) override { + intercepted_params_ = std::move(params); + } + + blink::mojom::OpenURLParamsPtr GetInterceptedParams() { + return std::move(intercepted_params_); + } + private: RenderFrameProxyHost* render_frame_proxy_host_; + std::u16string evil_origin_; + blink::mojom::OpenURLParamsPtr intercepted_params_; }; // Test verifying that a compromised renderer can't lie about the source_origin @@ -872,8 +881,8 @@ web_contents->GetMainFrame()->GetLastCommittedOrigin(); std::u16string evil_source_origin = base::UTF8ToUTF16(invalid_origin.Serialize()); - RouteMessageEventInterceptor mojo_interceptor(main_frame_proxy_host, - evil_source_origin); + RemoteFrameHostInterceptor mojo_interceptor(main_frame_proxy_host, + evil_source_origin); // Post a message from the subframe to the cross-site parent and intercept the // associated IPC message, changing it to simulate a compromised subframe @@ -885,40 +894,6 @@ kill_waiter.Wait()); } -// Intercepts calls to RenderFramHost's OpenURL mojo method, and -// store the passed parameter. -class OpenURLInterceptor - : public mojom::RenderFrameProxyHostInterceptorForTesting { - public: - explicit OpenURLInterceptor( - content::RenderFrameProxyHost* render_frame_proxy_host) - : render_frame_proxy_host_(render_frame_proxy_host), - intercepted_params_(blink::mojom::OpenURLParams::New()) { - render_frame_proxy_host_->frame_proxy_host_receiver_for_testing() - .SwapImplForTesting(this); - } - - ~OpenURLInterceptor() override = default; - - mojom::RenderFrameProxyHost* GetForwardingInterface() override { - return render_frame_proxy_host_; - } - - void OpenURL(blink::mojom::OpenURLParamsPtr params) override { - intercepted_params_ = std::move(params); - } - - blink::mojom::OpenURLParamsPtr GetInterceptedParams() { - return std::move(intercepted_params_); - } - - private: - content::RenderFrameProxyHost* render_frame_proxy_host_; - blink::mojom::OpenURLParamsPtr intercepted_params_; - - DISALLOW_COPY_AND_ASSIGN(OpenURLInterceptor); -}; - IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidRemoteNavigationInitiator) { // Explicitly isolating a.com helps ensure that this test is applicable on @@ -950,7 +925,7 @@ RenderFrameProxyHost* proxy = child_node->render_manager()->GetRenderFrameProxyHost(a_com_instance); - OpenURLInterceptor interceptor(proxy); + RemoteFrameHostInterceptor interceptor(proxy, std::u16string()); // Have the main frame request navigation in the "remote" subframe. This will // result in OpenURL Mojo message being sent to the RenderFrameProxyHost.
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc index a884726..e1b76102 100644 --- a/content/browser/service_worker/service_worker_version_browsertest.cc +++ b/content/browser/service_worker/service_worker_version_browsertest.cc
@@ -20,7 +20,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/test/bind.h" #include "base/time/time.h" @@ -94,12 +93,12 @@ void RunWithDelay(base::OnceClosure closure, base::TimeDelta delay) { base::RunLoop run_loop; - base::PostDelayedTask(FROM_HERE, {BrowserThread::UI}, - base::BindLambdaForTesting([&]() { - std::move(closure).Run(); - run_loop.Quit(); - }), - delay); + GetUIThreadTaskRunner({})->PostDelayedTask(FROM_HERE, + base::BindLambdaForTesting([&]() { + std::move(closure).Run(); + run_loop.Quit(); + }), + delay); run_loop.Run(); }
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 45b0ad3..0fa90c4 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -79,7 +79,6 @@ #include "content/common/content_navigation_policy.h" #include "content/common/frame.mojom-test-utils.h" #include "content/common/frame_messages.h" -#include "content/common/frame_proxy.mojom-test-utils.h" #include "content/common/input/actions_parser.h" #include "content/common/input/synthetic_pinch_gesture_params.h" #include "content/common/renderer.mojom.h"
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc index b3eb0513..a7c7448 100644 --- a/content/browser/utility_process_host.cc +++ b/content/browser/utility_process_host.cc
@@ -317,12 +317,6 @@ std::make_unique<UtilitySandboxedProcessLauncherDelegate>( sandbox_type_, env_, *cmd_line); -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - if (child_flags == ChildProcessHost::CHILD_LAUNCH_X86_64) { - delegate->set_launch_x86_64(true); - } -#endif // OS_MAC && ARCH_CPU_ARM64 - process_->LaunchWithPreloadedFiles(std::move(delegate), std::move(cmd_line), GetV8SnapshotFilesToPreload(), true); }
diff --git a/content/browser/utility_process_sandbox_browsertest.cc b/content/browser/utility_process_sandbox_browsertest.cc index 99e9394..4161c52f 100644 --- a/content/browser/utility_process_sandbox_browsertest.cc +++ b/content/browser/utility_process_sandbox_browsertest.cc
@@ -170,4 +170,9 @@ return name; }); +// In some configurations (e.g. Linux ASAN) GetSandboxTypesToTest() returns an +// empty list. Suppress runtime warnings about unparameterized tests. See +// https://crbug.com/1192206 +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UtilityProcessSandboxBrowserTest); + } // namespace content
diff --git a/content/browser/utility_sandbox_delegate.cc b/content/browser/utility_sandbox_delegate.cc index 3a968c4..57a5d4c 100644 --- a/content/browser/utility_sandbox_delegate.cc +++ b/content/browser/utility_sandbox_delegate.cc
@@ -74,12 +74,6 @@ } #endif // OS_POSIX -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) -bool UtilitySandboxedProcessLauncherDelegate::LaunchX86_64() { - return launch_x86_64_; -} -#endif // OS_MAC && ARCH_CPU_ARM64 - #if BUILDFLAG(USE_ZYGOTE_HANDLE) ZygoteHandle UtilitySandboxedProcessLauncherDelegate::GetZygote() { // If the sandbox has been disabled for a given type, don't use a zygote.
diff --git a/content/browser/utility_sandbox_delegate.h b/content/browser/utility_sandbox_delegate.h index cc2f1d4..8dcad0d 100644 --- a/content/browser/utility_sandbox_delegate.h +++ b/content/browser/utility_sandbox_delegate.h
@@ -49,22 +49,12 @@ base::EnvironmentMap GetEnvironment() override; #endif // OS_POSIX -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - // If true, the child process will be launched as x86_64 code under Rosetta - // translation. - void set_launch_x86_64(bool launch_x86_64) { launch_x86_64_ = launch_x86_64; } - bool LaunchX86_64() override; -#endif // OS_MAC && ARCH_CPU_ARM64 - private: #if defined(OS_POSIX) base::EnvironmentMap env_; #endif // OS_POSIX sandbox::policy::SandboxType sandbox_type_; base::CommandLine cmd_line_; -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - bool launch_x86_64_ = false; -#endif // OS_MAC && ARCH_CPU_ARM64 }; } // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index cdc048d4..3d08c2e 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3683,6 +3683,10 @@ load_params->was_opener_suppressed = true; load_params->has_user_gesture = has_user_gesture; load_params->impression = params.impression; + load_params->override_user_agent = + new_contents_impl->should_override_user_agent_in_new_tabs_ + ? NavigationController::UA_OVERRIDE_TRUE + : NavigationController::UA_OVERRIDE_FALSE; if (delegate_ && !is_guest && !delegate_->ShouldResumeRequestsForCreatedWindow()) { @@ -4394,6 +4398,14 @@ input_handler->CollapseSelection(); } +void WebContentsImpl::ScrollToTopOfDocument() { + ExecuteEditCommand("ScrollToBeginningOfDocument", base::nullopt); +} + +void WebContentsImpl::ScrollToBottomOfDocument() { + ExecuteEditCommand("ScrollToEndOfDocument", base::nullopt); +} + void WebContentsImpl::Replace(const std::u16string& word) { OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Replace"); auto* input_handler = GetFocusedFrameWidgetInputHandler();
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 35243d8f..a45ad650 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -445,6 +445,8 @@ void Delete() override; void SelectAll() override; void CollapseSelection() override; + void ScrollToTopOfDocument() override; + void ScrollToBottomOfDocument() override; void Replace(const std::u16string& word) override; void ReplaceMisspelling(const std::u16string& word) override; void NotifyContextMenuClosed(const GURL& link_followed) override;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index d4dccfbf..c92f22a 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -353,6 +353,7 @@ {"BlockCredentialedSubresources", features::kBlockCredentialedSubresources}, {"COLRV1Fonts", blink::features::kCOLRV1Fonts}, + {"CSSContainerQueries", blink::features::kCSSContainerQueries}, {"CompositeAfterPaint", blink::features::kCompositeAfterPaint}, {"ComputePressure", blink::features::kComputePressure}, {"CSSColorSchemeUARendering", features::kCSSColorSchemeUARendering},
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index e9751bf..d009abe 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -297,7 +297,6 @@ "mac/attributed_string_type_converters.mm", "mac/font_loader.h", "mac/font_loader.mm", - "sandbox_init_mac.cc", ] deps += [ ":mac_helpers", @@ -440,7 +439,6 @@ "field_trial_recorder.mojom", "frame.mojom", "frame_messages.mojom", - "frame_proxy.mojom", "histogram_fetcher.mojom", "input/input_injector.mojom", "media/media_log_records.mojom",
diff --git a/content/common/child_process_host_impl.cc b/content/common/child_process_host_impl.cc index fe07a994..665bc28 100644 --- a/content/common/child_process_host_impl.cc +++ b/content/common/child_process_host_impl.cc
@@ -87,11 +87,7 @@ #if defined(OS_MAC) std::string child_base_name = child_path.BaseName().value(); - if (flags != CHILD_NORMAL && base::mac::AmIBundled() -#if defined(ARCH_CPU_ARM64) - && flags != CHILD_LAUNCH_X86_64 -#endif // ARCH_CPU_ARM64 - ) { + if (flags != CHILD_NORMAL && base::mac::AmIBundled()) { // This is a specialized helper, with the |child_path| at // ../Framework.framework/Versions/X/Helpers/Chromium Helper.app/Contents/ // MacOS/Chromium Helper. Go back up to the "Helpers" directory to select
diff --git a/content/common/content_switches_internal.cc b/content/common/content_switches_internal.cc index 95eacdb..7cd1e042 100644 --- a/content/common/content_switches_internal.cc +++ b/content/common/content_switches_internal.cc
@@ -127,7 +127,7 @@ const base::CommandLine& command_line, const char* switch_name) { using NativeString = base::CommandLine::StringType; - using NativeStringPiece = base::BasicStringPiece<NativeString>; + using NativeStringPiece = base::CommandLine::StringPieceType; std::vector<std::string> features; if (!command_line.HasSwitch(switch_name))
diff --git a/content/common/frame_proxy.mojom b/content/common/frame_proxy.mojom deleted file mode 100644 index be07fec..0000000 --- a/content/common/frame_proxy.mojom +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2019 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. - -module content.mojom; - -import "third_party/blink/public/mojom/frame/frame.mojom"; -import "ui/gfx/geometry/mojom/geometry.mojom"; - -// Mojo interface for communicating from RenderFrameProxy to -// RenderFrameProxyHost. Implemented by the browser process, called by renderer -// processes. -interface RenderFrameProxyHost { - // TODO(dtapuska): Keep this interface for now. All methods have moved to - // blink::RemoteFrameHost but we might still need this. - - // Requests that the given URL be opened in the specified manner. - OpenURL(blink.mojom.OpenURLParams params); -}; - -// Mojo interface for communicating from RenderFrameProxyHost to -// RenderFrameProxy. Implemented by renderer processes, called by the browser -// process. -// TODO(https://crbug.com/1166719): Remove this interface. -interface RenderFrameProxy { -};
diff --git a/content/common/sandbox_init_mac.cc b/content/common/sandbox_init_mac.cc deleted file mode 100644 index 34191d1e..0000000 --- a/content/common/sandbox_init_mac.cc +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright (c) 2011 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 "content/public/common/sandbox_init.h" - -#include "base/bind.h" -#include "base/check.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "gpu/config/gpu_feature_info.h" -#include "gpu/config/gpu_info.h" -#include "gpu/config/gpu_info_collector.h" -#include "gpu/config/gpu_preferences.h" -#include "gpu/config/gpu_switches.h" -#include "gpu/config/gpu_switching.h" -#include "gpu/config/gpu_util.h" -#include "media/gpu/mac/vt_video_decode_accelerator_mac.h" -#include "sandbox/mac/seatbelt.h" -#include "sandbox/mac/seatbelt_exec.h" -#include "sandbox/policy/mac/sandbox_mac.h" -#include "sandbox/policy/sandbox.h" -#include "sandbox/policy/sandbox_type.h" -#include "ui/gl/init/gl_factory.h" - -namespace content { - -namespace { - -// Helper method to make a closure from a closure. -base::OnceClosure MaybeWrapWithGPUSandboxHook( - sandbox::policy::SandboxType sandbox_type, - base::OnceClosure original) { - if (sandbox_type != sandbox::policy::SandboxType::kGpu) - return original; - - return base::BindOnce( - [](base::OnceClosure arg) { - // We need to gather GPUInfo and compute GpuFeatureInfo here, so we can - // decide if initializing core profile or compatibility profile GL, - // depending on gpu driver bug workarounds. - gpu::GPUInfo gpu_info; - auto* command_line = base::CommandLine::ForCurrentProcess(); - gpu::CollectBasicGraphicsInfo(command_line, &gpu_info); - gpu::CacheGPUInfo(gpu_info); - gpu::GpuPreferences gpu_preferences; - if (command_line->HasSwitch(switches::kGpuPreferences)) { - std::string value = - command_line->GetSwitchValueASCII(switches::kGpuPreferences); - bool success = gpu_preferences.FromSwitchValue(value); - CHECK(success); - } - bool needs_more_info = false; - gpu::GpuFeatureInfo gpu_feature_info = gpu::ComputeGpuFeatureInfo( - gpu_info, gpu_preferences, command_line, &needs_more_info); - gpu::CacheGpuFeatureInfo(gpu_feature_info); - if (gpu::SwitchableGPUsSupported(gpu_info, *command_line)) { - gpu::InitializeSwitchableGPUs( - gpu_feature_info.enabled_gpu_driver_bug_workarounds); - } - gpu::EnableSwiftShaderIfNeeded( - command_line, gpu_feature_info, - gpu_preferences.disable_software_rasterizer, needs_more_info); - // Preload either the desktop GL or SwiftShader so, depending on the - // --use-gl flag. - gl::init::InitializeGLOneOff(); - - // Preload VideoToolbox. - media::InitializeVideoToolbox(); - - // Invoke original hook. - if (!arg.is_null()) - std::move(arg).Run(); - }, - std::move(original)); -} - -// Fill in |sandbox_type| based on the command line. Returns false if the -// current process type doesn't need to be sandboxed or if the sandbox was -// disabled from the command line. -bool GetSandboxTypeFromCommandLine(sandbox::policy::SandboxType* sandbox_type) { - DCHECK(sandbox_type); - - auto* command_line = base::CommandLine::ForCurrentProcess(); - *sandbox_type = sandbox::policy::SandboxTypeFromCommandLine(*command_line); - if (IsUnsandboxedSandboxType(*sandbox_type)) - return false; - - if (command_line->HasSwitch(sandbox::switches::kSeatbeltClientName)) { - CHECK(sandbox::Seatbelt::IsSandboxed()); - // Do not enable the sandbox if V2 is already enabled. - return false; - } - - return true; -} - -} // namespace - -bool InitializeSandbox(sandbox::policy::SandboxType sandbox_type) { - return sandbox::policy::Sandbox::Initialize( - sandbox_type, - MaybeWrapWithGPUSandboxHook(sandbox_type, base::OnceClosure())); -} - -bool InitializeSandbox(base::OnceClosure post_warmup_hook) { - sandbox::policy::SandboxType sandbox_type = - sandbox::policy::SandboxType::kNoSandbox; - return !GetSandboxTypeFromCommandLine(&sandbox_type) || - sandbox::policy::Sandbox::Initialize( - sandbox_type, MaybeWrapWithGPUSandboxHook( - sandbox_type, std::move(post_warmup_hook))); -} - -bool InitializeSandbox() { - return InitializeSandbox(base::OnceClosure()); -} - -} // namespace content
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java index 9bb6fcf7..898a90b 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
@@ -7,9 +7,6 @@ import android.annotation.TargetApi; import android.app.Activity; import android.app.SearchManager; -import android.content.ClipData; -import android.content.ClipDescription; -import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -19,11 +16,7 @@ import android.os.Build; import android.os.Handler; import android.provider.Browser; -import android.text.Spanned; import android.text.TextUtils; -import android.text.style.CharacterStyle; -import android.text.style.ParagraphStyle; -import android.text.style.UpdateAppearance; import android.view.ActionMode; import android.view.HapticFeedbackConstants; import android.view.Menu; @@ -63,6 +56,7 @@ import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.base.Clipboard; import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.MenuSourceType; import org.chromium.ui.base.ViewAndroidDelegate; @@ -514,7 +508,10 @@ return; } - if (!supportsFloatingActionMode() && !canPaste() && mNonSelectionCallback == null) return; + if (!supportsFloatingActionMode() && !Clipboard.getInstance().canPaste() + && mNonSelectionCallback == null) { + return; + } destroyPastePopup(); PastePopupMenu.PastePopupMenuDelegate delegate = new PastePopupMenu.PastePopupMenuDelegate() { @@ -532,7 +529,7 @@ @Override public boolean canPaste() { - return SelectionPopupControllerImpl.this.canPaste(); + return Clipboard.getInstance().canPaste(); } @Override @@ -807,7 +804,7 @@ } private void removeActionMenuItemsIfNecessary(Menu menu) { - if (!isFocusedNodeEditable() || !canPaste()) { + if (!isFocusedNodeEditable() || !Clipboard.getInstance().canPaste()) { menu.removeItem(R.id.select_action_menu_paste); menu.removeItem(R.id.select_action_menu_paste_as_plain_text); } @@ -844,51 +841,19 @@ } } - private boolean canPaste() { - ClipboardManager clipMgr = - (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - return clipMgr.hasPrimaryClip(); - } - - // Check if this Spanned is formatted text. - private boolean hasStyleSpan(Spanned spanned) { - // Only check against those three classes below, which could affect text appearance, since - // there are other kind of classes won't affect appearance. - Class<?>[] styleClasses = { - CharacterStyle.class, ParagraphStyle.class, UpdateAppearance.class}; - for (Class<?> clazz : styleClasses) { - if (spanned.nextSpanTransition(-1, spanned.length(), clazz) < spanned.length()) { - return true; - } - } - return false; - } - - // Check if need to show "paste as plain text" option. - // Don't show "paste as plain text" when "paste" and "paste as plain text" would do exactly the - // same. + /** + * Check if need to show "paste as plain text" option. + * "paste as plain text" option needs clibpoard content is rich text, and editor supports rich + * text as well. + */ @VisibleForTesting public boolean canPasteAsPlainText() { - // String resource "paste_as_plain_text" only exist in O. - // Also this is an O feature, we need to make it consistant with TextView. + // String resource "paste_as_plain_text" only exist in O+. + // Also this is an O feature, we need to make it consistent with TextView. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false; if (!mCanEditRichly) return false; - ClipboardManager clipMgr = - (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - if (!clipMgr.hasPrimaryClip()) return false; - ClipData clipData = clipMgr.getPrimaryClip(); - ClipDescription description = clipData.getDescription(); - CharSequence text = clipData.getItemAt(0).getText(); - boolean isPlainType = description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN); - // On Android, Spanned could be copied to Clipboard as plain_text MIME type, but in some - // cases, Spanned could have text format, we need to show "paste as plain text" when - // that happens. - if (isPlainType && (text instanceof Spanned)) { - Spanned spanned = (Spanned) text; - if (hasStyleSpan(spanned)) return true; - } - return description.hasMimeType(ClipDescription.MIMETYPE_TEXT_HTML); + return Clipboard.getInstance().canPasteAsPlainText(); } private void updateAssistMenuItem(Menu menu) {
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index bb9c1d0..3789a44 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -745,6 +745,8 @@ virtual void Delete() = 0; virtual void SelectAll() = 0; virtual void CollapseSelection() = 0; + virtual void ScrollToTopOfDocument() = 0; + virtual void ScrollToBottomOfDocument() = 0; // Adjust the selection starting and ending points in the focused frame by // the given amounts. A negative amount moves the selection towards the
diff --git a/content/public/common/cdm_info.h b/content/public/common/cdm_info.h index a676664..a637c57 100644 --- a/content/public/common/cdm_info.h +++ b/content/public/common/cdm_info.h
@@ -12,7 +12,6 @@ #include "base/files/file_path.h" #include "base/token.h" #include "base/version.h" -#include "build/build_config.h" #include "content/common/content_export.h" #include "media/base/content_decryption_module.h" #include "media/base/encryption_scheme.h" @@ -85,12 +84,6 @@ // For example, com.example.somekeysystem.a and com.example.somekeysystem.b // are both sub key systems of com.example.somekeysystem. bool supports_sub_key_systems; - -#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) - // If true, the child process will be launched as x86_64 code under Rosetta - // translation. - bool launch_x86_64 = false; -#endif // OS_MAC && ARCH_CPU_ARM64 }; } // namespace content
diff --git a/content/public/common/child_process_host.h b/content/public/common/child_process_host.h index 69b8743b..c73a188 100644 --- a/content/public/common/child_process_host.h +++ b/content/public/common/child_process_host.h
@@ -117,15 +117,6 @@ // third-party plug-ins. CHILD_PLUGIN, -#if defined(ARCH_CPU_ARM64) - // Launch the child process as CHILD_NORMAL, but as x86_64 code under - // Rosetta translation. The executable being launched must contain x86_64 - // code, either as a thin Mach-O file targeting x86_64, or a fat file with - // an x86_64 slice. Aside from the architecture, semantics are identical to - // CHILD_NORMAL, and this cannot be combined with any other CHILD_* values. - CHILD_LAUNCH_X86_64, -#endif // ARCH_CPU_ARM64 - // Marker for the start of embedder-specific helper child process types. // Values greater than CHILD_EMBEDDER_FIRST are reserved to be used by the // embedder to add custom process types and will be resolved via
diff --git a/content/public/common/sandbox_init.h b/content/public/common/sandbox_init.h index 244f8b2a..69a9efe 100644 --- a/content/public/common/sandbox_init.h +++ b/content/public/common/sandbox_init.h
@@ -54,30 +54,6 @@ const base::HandlesToInheritVector& handles_to_inherit, base::Process* process); -#elif defined(OS_MAC) - -// Initialize the sandbox of the given |sandbox_type|, optionally specifying a -// directory to allow access to. Note specifying a directory needs to be -// supported by the sandbox profile associated with the given |sandbox_type|. -// -// Returns true if the sandbox was initialized succesfully, false if an error -// occurred. If process_type isn't one that needs sandboxing, no action is -// taken and true is always returned. -CONTENT_EXPORT bool InitializeSandbox( - sandbox::policy::SandboxType sandbox_type); - -// Initialize the sandbox for renderer, gpu, utility, worker, and plugin -// processes, depending on the command line flags. For the browser process which -// is not sandboxed, this call is a no-op. -// Returns true if the sandbox was initialized succesfully, false if an error -// occurred. If process_type isn't one that needs sandboxing, true is always -// returned. -CONTENT_EXPORT bool InitializeSandbox(); - -// Initializes the sandbox, as described above, but executes the callback after -// warmup and before initialization. -CONTENT_EXPORT bool InitializeSandbox(base::OnceClosure post_warmup_hook); - #elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_NACL_NONSFI) // Initialize a seccomp-bpf sandbox. |policy| may not be NULL.
diff --git a/content/public/common/sandboxed_process_launcher_delegate.cc b/content/public/common/sandboxed_process_launcher_delegate.cc index 237dd086..f842207c 100644 --- a/content/public/common/sandboxed_process_launcher_delegate.cc +++ b/content/public/common/sandboxed_process_launcher_delegate.cc
@@ -64,12 +64,6 @@ return false; } -#if defined(ARCH_CPU_ARM64) -bool SandboxedProcessLauncherDelegate::LaunchX86_64() { - return false; -} -#endif // ARCH_CPU_ARM64 - #endif // OS_MAC } // namespace content
diff --git a/content/public/common/sandboxed_process_launcher_delegate.h b/content/public/common/sandboxed_process_launcher_delegate.h index 8b14094..ad8c219 100644 --- a/content/public/common/sandboxed_process_launcher_delegate.h +++ b/content/public/common/sandboxed_process_launcher_delegate.h
@@ -61,10 +61,6 @@ // Whether or not to enable CPU security mitigations against side-channel // attacks. See base::LaunchOptions::enable_cpu_security_mitigations. virtual bool EnableCpuSecurityMitigations(); - -#if defined(ARCH_CPU_ARM64) - virtual bool LaunchX86_64(); -#endif // ARCH_CPU_ARM64 #endif // OS_MAC };
diff --git a/content/public/test/browser_task_environment_unittest.cc b/content/public/test/browser_task_environment_unittest.cc index b8e70bc..7e3e3eb 100644 --- a/content/public/test/browser_task_environment_unittest.cc +++ b/content/public/test/browser_task_environment_unittest.cc
@@ -12,7 +12,6 @@ #include "base/dcheck_is_on.h" #include "base/synchronization/waitable_event.h" #include "base/task/current_thread.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/test/bind.h" #include "build/build_config.h" @@ -201,7 +200,7 @@ { GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::DoNothing()); }, kDeathMatcher); EXPECT_DEATH_IF_SUPPORTED( - { base::PostTask(FROM_HERE, {BrowserThread::UI}, base::DoNothing()); }, + { GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::DoNothing()); }, kDeathMatcher); } @@ -216,7 +215,7 @@ { GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::DoNothing()); }, kDeathMatcher); EXPECT_DEATH_IF_SUPPORTED( - { base::PostTask(FROM_HERE, {BrowserThread::IO}, base::DoNothing()); }, + { GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::DoNothing()); }, kDeathMatcher); }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index e347d8c..9e871c08 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -539,10 +539,11 @@ info->initiator_origin_trial_features.end()); blink::NavigationDownloadPolicy download_policy; - RenderFrameImpl::MaybeSetDownloadFramePolicy( - info->is_opener_navigation, info->url_request, current_origin, + download_policy.ApplyDownloadFramePolicy( + info->is_opener_navigation, info->url_request.HasUserGesture(), + info->url_request.RequestorOrigin().CanAccess(current_origin), has_download_sandbox_flag, info->blocking_downloads_in_sandbox_enabled, - from_ad, &download_policy); + from_ad); return mojom::CommonNavigationParams::New( info->url_request.Url(), info->url_request.RequestorOrigin(), @@ -1922,55 +1923,6 @@ return nullptr; } -// static -void RenderFrameImpl::MaybeSetDownloadFramePolicy( - bool is_opener_navigation, - const blink::WebURLRequest& request, - const blink::WebSecurityOrigin& current_origin, - bool has_download_sandbox_flag, - bool blocking_downloads_in_sandbox_enabled, - bool from_ad, - blink::NavigationDownloadPolicy* download_policy) { - bool has_gesture = request.HasUserGesture(); - if (!has_gesture) { - download_policy->SetAllowed(blink::NavigationDownloadType::kNoGesture); - } - - // Disallow downloads on an opener if the requestor is cross origin. - // See crbug.com/632514. - if (is_opener_navigation && - !request.RequestorOrigin().CanAccess(current_origin)) { - download_policy->SetDisallowed( - blink::NavigationDownloadType::kOpenerCrossOrigin); - } - - if (has_download_sandbox_flag) { - if (blocking_downloads_in_sandbox_enabled) { - download_policy->SetDisallowed(blink::NavigationDownloadType::kSandbox); - } else { - download_policy->SetAllowed(blink::NavigationDownloadType::kSandbox); - } - } - - if (from_ad) { - download_policy->SetAllowed(blink::NavigationDownloadType::kAdFrame); - if (!has_gesture) { - if (base::FeatureList::IsEnabled( - blink::features:: - kBlockingDownloadsInAdFrameWithoutUserActivation)) { - download_policy->SetDisallowed( - blink::NavigationDownloadType::kAdFrameNoGesture); - } else { - download_policy->SetAllowed( - blink::NavigationDownloadType::kAdFrameNoGesture); - } - } - } - - download_policy->blocking_downloads_in_sandbox_enabled = - blocking_downloads_in_sandbox_enabled; -} - blink::WebURL RenderFrameImpl::OverrideFlashEmbedWithHTML( const blink::WebURL& url) { return GetContentClient()->renderer()->OverrideFlashEmbedWithHTML(url); @@ -5604,11 +5556,12 @@ current_frame_has_download_sandbox_flag; bool from_ad = info->initiator_frame_is_ad || frame_->IsAdSubframe(); - MaybeSetDownloadFramePolicy(info->is_opener_navigation, info->url_request, - frame_->GetSecurityOrigin(), - has_download_sandbox_flag, - info->blocking_downloads_in_sandbox_enabled, - from_ad, ¶ms->download_policy); + params->download_policy.ApplyDownloadFramePolicy( + info->is_opener_navigation, info->url_request.HasUserGesture(), + info->url_request.RequestorOrigin().CanAccess( + frame_->GetSecurityOrigin()), + has_download_sandbox_flag, info->blocking_downloads_in_sandbox_enabled, + from_ad); GetFrameHost()->OpenURL(std::move(params)); }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 9b0285f80..a2c21ad 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -126,7 +126,6 @@ class WebFrameRequestBlocker; class WebLocalFrame; class WebMediaStreamDeviceObserver; -class WebSecurityOrigin; class WebString; class WebURL; struct FramePolicy; @@ -260,17 +259,6 @@ // ID. static blink::WebFrame* ResolveWebFrame(int opener_frame_routing_id); - // Possibly set the kOpenerCrossOrigin and kSandboxNoGesture policy in - // |download_policy|. - static void MaybeSetDownloadFramePolicy( - bool is_opener_navigation, - const blink::WebURLRequest& request, - const blink::WebSecurityOrigin& current_origin, - bool has_download_sandbox_flag, - bool blocking_downloads_in_sandbox_enabled, - bool from_ad, - blink::NavigationDownloadPolicy* download_policy); - // Overwrites the given URL to use an HTML5 embed if possible. blink::WebURL OverrideFlashEmbedWithHTML(const blink::WebURL& url) override;
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 41d80aa7..7fd2cad 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -28,6 +28,7 @@ #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "third_party/blink/public/common/frame/frame_policy.h" #include "third_party/blink/public/common/navigation/impression.h" +#include "third_party/blink/public/common/navigation/navigation_policy.h" #include "third_party/blink/public/common/permissions_policy/permissions_policy.h" #include "third_party/blink/public/mojom/frame/frame.mojom.h" #include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom.h" @@ -288,10 +289,6 @@ associated_interfaces_.TryBindInterface(interface_name, &handle); } else if (interface_name == blink::mojom::RemoteMainFrame::Name_) { associated_interfaces_.TryBindInterface(interface_name, &handle); - } else if (interface_name == content::mojom::RenderFrameProxy::Name_) { - render_frame_proxy_receiver_.Bind( - mojo::PendingAssociatedReceiver<mojom::RenderFrameProxy>( - std::move(handle))); } } @@ -318,64 +315,6 @@ delete this; } -void RenderFrameProxy::Navigate( - const blink::WebURLRequest& request, - bool should_replace_current_entry, - bool is_opener_navigation, - bool initiator_frame_has_download_sandbox_flag, - bool blocking_downloads_in_sandbox_enabled, - bool initiator_frame_is_ad, - blink::CrossVariantMojoRemote<blink::mojom::BlobURLTokenInterfaceBase> - blob_url_token, - const base::Optional<blink::WebImpression>& impression, - const blink::LocalFrameToken* initiator_frame_token, - blink::CrossVariantMojoRemote< - blink::mojom::PolicyContainerHostKeepAliveHandleInterfaceBase> - initiator_policy_container_keep_alive_handle) { - // The request must always have a valid initiator origin. - DCHECK(!request.RequestorOrigin().IsNull()); - - auto params = blink::mojom::OpenURLParams::New(); - params->url = request.Url(); - params->initiator_origin = request.RequestorOrigin(); - params->post_body = blink::GetRequestBodyForWebURLRequest(request); - DCHECK_EQ(!!params->post_body, request.HttpMethod().Utf8() == "POST"); - params->extra_headers = - blink::GetWebURLRequestHeadersAsString(request).Latin1(); - params->referrer = blink::mojom::Referrer::New( - blink::WebStringToGURL(request.ReferrerString()), - request.GetReferrerPolicy()); - params->disposition = WindowOpenDisposition::CURRENT_TAB; - params->should_replace_current_entry = should_replace_current_entry; - params->user_gesture = request.HasUserGesture(); - params->triggering_event_info = blink::mojom::TriggeringEventInfo::kUnknown; - params->blob_url_token = std::move(blob_url_token); - params->initiator_policy_container_keep_alive_handle = - std::move(initiator_policy_container_keep_alive_handle); - params->initiator_frame_token = base::OptionalFromPtr(initiator_frame_token); - - if (impression) - params->impression = blink::ConvertWebImpressionToImpression(*impression); - - // Note: For the AdFrame/Sandbox download policy here it only covers the case - // where the navigation initiator frame is ad. The download_policy may be - // further augmented in RenderFrameProxyHost::OnOpenURL if the navigating - // frame is ad or sandboxed. - RenderFrameImpl::MaybeSetDownloadFramePolicy( - is_opener_navigation, request, web_frame_->GetSecurityOrigin(), - initiator_frame_has_download_sandbox_flag, - blocking_downloads_in_sandbox_enabled, initiator_frame_is_ad, - ¶ms->download_policy); - - GetFrameProxyHost()->OpenURL(std::move(params)); -} - -mojom::RenderFrameProxyHost* RenderFrameProxy::GetFrameProxyHost() { - if (!frame_proxy_host_remote_.is_bound()) - GetRemoteAssociatedInterfaces()->GetInterface(&frame_proxy_host_remote_); - return frame_proxy_host_remote_.get(); -} - blink::AssociatedInterfaceProvider* RenderFrameProxy::GetRemoteAssociatedInterfaces() { if (!remote_associated_interfaces_) {
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 08a69a1..47acde0 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -10,7 +10,6 @@ #include "cc/paint/paint_canvas.h" #include "content/common/content_export.h" #include "content/common/frame_messages.h" -#include "content/common/frame_proxy.mojom.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" #include "mojo/public/cpp/bindings/associated_receiver.h" @@ -60,8 +59,7 @@ // RenderFrame is created for it. class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener, public IPC::Sender, - public blink::WebRemoteFrameClient, - public mojom::RenderFrameProxy { + public blink::WebRemoteFrameClient { public: // This method should be used to create a RenderFrameProxy, which will replace // an existing RenderFrame during its cross-process navigation from the @@ -139,21 +137,6 @@ void FrameDetached(DetachType type) override; blink::AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override; - void Navigate( - const blink::WebURLRequest& request, - bool should_replace_current_entry, - bool is_opener_navigation, - bool initiator_frame_has_download_sandbox_flag, - bool blocking_downloads_in_sandbox_enabled, - bool initiator_frame_is_ad, - blink::CrossVariantMojoRemote<blink::mojom::BlobURLTokenInterfaceBase> - blob_url_token, - const base::Optional<blink::WebImpression>& impression, - const blink::LocalFrameToken* initiator_frame_token, - blink::CrossVariantMojoRemote< - blink::mojom::PolicyContainerHostKeepAliveHandleInterfaceBase> - initiator_policy_container_keep_alive_handle) override; - void DidStartLoading(); private: @@ -162,8 +145,6 @@ void Init(blink::WebRemoteFrame* frame, RenderViewImpl* render_view); - mojom::RenderFrameProxyHost* GetFrameProxyHost(); - // The |AgentSchedulingGroup| this proxy is associated with. NOTE: This is // different than the |AgentSchedulingGroup| associated with the frame being // proxied. @@ -177,14 +158,9 @@ // Provides the mojo interface to this RenderFrameProxy's // RenderFrameProxyHost. - mojo::AssociatedRemote<mojom::RenderFrameProxyHost> frame_proxy_host_remote_; std::unique_ptr<blink::AssociatedInterfaceProvider> remote_associated_interfaces_; - // Mojo receiver to this content::mojom::RenderFrameProxy. - mojo::AssociatedReceiver<mojom::RenderFrameProxy> - render_frame_proxy_receiver_{this}; - RenderViewImpl* render_view_ = nullptr; service_manager::BinderRegistry binder_registry_;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index c8ef482..e459063 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1875,6 +1875,7 @@ "../browser/gpu/gpu_data_manager_testing_entry_enums_autogen.h", "../browser/gpu/gpu_data_manager_testing_exceptions_autogen.h", "../browser/handwriting/handwriting_recognition_service_impl_unittest.cc", + "../browser/histograms_monitor_unittest.cc", "../browser/idle/idle_manager_unittest.cc", "../browser/indexed_db/fake_indexed_db_metadata_coding.cc", "../browser/indexed_db/fake_indexed_db_metadata_coding.h",
diff --git a/content/test/fuzzer/code_cache_host_mojolpm_fuzzer.cc b/content/test/fuzzer/code_cache_host_mojolpm_fuzzer.cc index 66435f0d..f15ccfb 100644 --- a/content/test/fuzzer/code_cache_host_mojolpm_fuzzer.cc +++ b/content/test/fuzzer/code_cache_host_mojolpm_fuzzer.cc
@@ -10,7 +10,6 @@ #include "base/command_line.h" #include "base/files/scoped_temp_dir.h" #include "base/i18n/icu_util.h" -#include "base/task/post_task.h" #include "base/test/test_switches.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" @@ -19,6 +18,7 @@ #include "content/browser/renderer_host/code_cache_host_impl.h" // [nogncheck] #include "content/browser/storage_partition_impl_map.h" // [nogncheck] #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_content_client_initializer.h" @@ -195,10 +195,11 @@ void CodeCacheHostTestcase::SetUp() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&CodeCacheHostTestcase::SetUpOnUIThread, - base::Unretained(this)), - run_loop.QuitClosure()); + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, + base::BindOnce(&CodeCacheHostTestcase::SetUpOnUIThread, + base::Unretained(this)), + run_loop.QuitClosure()); run_loop.Run(); } @@ -220,8 +221,8 @@ void CodeCacheHostTestcase::TearDown() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&CodeCacheHostTestcase::TearDownOnUIThread, base::Unretained(this)), run_loop.QuitClosure()); @@ -265,13 +266,13 @@ case Action::kRunThread: { if (action.run_thread().id()) { base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - run_loop.QuitClosure()); + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); } else { base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTask(FROM_HERE, {content::BrowserThread::IO}, - run_loop.QuitClosure()); + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); } } break; @@ -319,8 +320,8 @@ } base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&CodeCacheHostTestcase::AddCodeCacheHostImpl, base::Unretained(this), id, renderer_id, *origin, std::move(receiver)),
diff --git a/content/test/fuzzer/controller_presentation_service_delegate_for_fuzzing.cc b/content/test/fuzzer/controller_presentation_service_delegate_for_fuzzing.cc index 3b2ef33..888320b8 100644 --- a/content/test/fuzzer/controller_presentation_service_delegate_for_fuzzing.cc +++ b/content/test/fuzzer/controller_presentation_service_delegate_for_fuzzing.cc
@@ -9,7 +9,6 @@ #include "content/test/fuzzer/controller_presentation_service_delegate_for_fuzzing.h" #include "base/notreached.h" -#include "base/task/post_task.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "third_party/blink/public/mojom/presentation/presentation.mojom-mojolpm.h" @@ -158,8 +157,8 @@ GURL url; if (!mojolpm::FromProto(proto_url, url)) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ControllerPresentationServiceDelegateForFuzzing:: CallListenersGetAvailabilityUrl, GetWeakPtr(), std::move(url))); @@ -184,8 +183,8 @@ blink::mojom::ScreenAvailability screen_availability; if (!mojolpm::FromProto(proto_screen_availability, screen_availability)) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ControllerPresentationServiceDelegateForFuzzing:: CallListenersOnScreenAvailabilityChanged, GetWeakPtr(), std::move(url), @@ -210,8 +209,8 @@ blink::mojom::PresentationConnectionResultPtr result; if (!mojolpm::FromProto(proto_result, result)) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ControllerPresentationServiceDelegateForFuzzing:: CallSetDefaultPresentationUrls, GetWeakPtr(), std::move(result))); @@ -234,8 +233,8 @@ blink::mojom::PresentationConnectionResultPtr result; if (!mojolpm::FromProto(proto_result, result)) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ControllerPresentationServiceDelegateForFuzzing:: CallStartPresentationSuccess, GetWeakPtr(), std::move(result))); @@ -259,8 +258,8 @@ blink::mojom::PresentationErrorPtr error; if (!mojolpm::FromProto(proto_error, error)) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ControllerPresentationServiceDelegateForFuzzing:: CallStartPresentationError, GetWeakPtr(), std::move(error))); @@ -282,8 +281,8 @@ blink::mojom::PresentationConnectionResultPtr result; if (!mojolpm::FromProto(proto_result, result)) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ControllerPresentationServiceDelegateForFuzzing:: CallReconnectPresentationSuccess, GetWeakPtr(), std::move(result))); @@ -305,8 +304,8 @@ blink::mojom::PresentationErrorPtr error; if (!mojolpm::FromProto(proto_error, error)) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ControllerPresentationServiceDelegateForFuzzing:: CallReconnectPresentationError, GetWeakPtr(), std::move(error))); @@ -329,8 +328,8 @@ blink::mojom::PresentationConnectionState connection_state; if (!mojolpm::FromProto(proto_connection_state, connection_state)) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ControllerPresentationServiceDelegateForFuzzing:: CallListenForConnectionStateChangeStateChanged, GetWeakPtr(), std::move(connection_state)));
diff --git a/content/test/fuzzer/file_system_manager_mojolpm_fuzzer.cc b/content/test/fuzzer/file_system_manager_mojolpm_fuzzer.cc index e7f5789..453535e 100644 --- a/content/test/fuzzer/file_system_manager_mojolpm_fuzzer.cc +++ b/content/test/fuzzer/file_system_manager_mojolpm_fuzzer.cc
@@ -10,7 +10,6 @@ #include "base/command_line.h" #include "base/files/scoped_temp_dir.h" #include "base/i18n/icu_util.h" -#include "base/task/post_task.h" #include "base/test/test_switches.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" @@ -19,6 +18,7 @@ #include "content/browser/file_system/file_system_manager_impl.h" // nogncheck #include "content/browser/storage_partition_impl_map.h" // nogncheck #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_content_client_initializer.h" @@ -187,16 +187,16 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::RunLoop io_run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {BrowserThread::IO}, + GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&FileSystemManagerTestcase::SetUpOnIOThread, base::Unretained(this)), io_run_loop.QuitClosure()); io_run_loop.Run(); base::RunLoop ui_run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&FileSystemManagerTestcase::SetUpOnUIThread, base::Unretained(this)), ui_run_loop.QuitClosure()); @@ -210,8 +210,7 @@ blob_storage_context_ = base::MakeRefCounted<ChromeBlobStorageContext>(); blob_storage_context_->InitializeOnIOThread( - temp_dir_.GetPath(), temp_dir_.GetPath(), - base::CreateSingleThreadTaskRunner({BrowserThread::IO})); + temp_dir_.GetPath(), temp_dir_.GetPath(), GetIOThreadTaskRunner({})); } void FileSystemManagerTestcase::SetUpOnUIThread() { @@ -236,16 +235,16 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::RunLoop ui_run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&FileSystemManagerTestcase::TearDownOnUIThread, base::Unretained(this)), ui_run_loop.QuitClosure()); ui_run_loop.Run(); base::RunLoop io_run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&FileSystemManagerTestcase::TearDownOnIOThread, base::Unretained(this)), io_run_loop.QuitClosure()); @@ -293,13 +292,13 @@ case Action::kRunThread: if (action.run_thread().id()) { base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTask(FROM_HERE, {BrowserThread::UI}, - run_loop.QuitClosure()); + GetUIThreadTaskRunner({})->PostTask(FROM_HERE, + run_loop.QuitClosure()); run_loop.Run(); } else { base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTask(FROM_HERE, {BrowserThread::IO}, - run_loop.QuitClosure()); + GetIOThreadTaskRunner({})->PostTask(FROM_HERE, + run_loop.QuitClosure()); run_loop.Run(); } break; @@ -343,8 +342,8 @@ auto receiver = remote.BindNewPipeAndPassReceiver(); base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&FileSystemManagerTestcase::AddFileSystemManagerImpl, base::Unretained(this), id, render_process_id, std::move(receiver)),
diff --git a/content/test/fuzzer/presentation_service_mojolpm_fuzzer.cc b/content/test/fuzzer/presentation_service_mojolpm_fuzzer.cc index 186b191..e83c5f72 100644 --- a/content/test/fuzzer/presentation_service_mojolpm_fuzzer.cc +++ b/content/test/fuzzer/presentation_service_mojolpm_fuzzer.cc
@@ -16,7 +16,6 @@ #include "base/macros.h" #include "base/optional.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/test/test_switches.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" @@ -27,6 +26,7 @@ #include "content/browser/presentation/presentation_test_utils.h" #include "content/browser/site_instance_impl.h" // nogncheck #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/presentation_request.h" #include "content/public/browser/presentation_service_delegate.h" #include "content/public/browser/site_instance.h" @@ -215,13 +215,13 @@ case Action::kRunThread: { if (action.run_thread().id()) { base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - run_loop.QuitClosure()); + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); } else { base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTask(FROM_HERE, {content::BrowserThread::IO}, - run_loop.QuitClosure()); + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); } } break; @@ -260,8 +260,8 @@ RenderViewHostTestHarness::SetUp(); base::RunLoop run_loop; - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&PresentationServiceTestcase::SetUpOnUIThread, base::Unretained(this)), run_loop.QuitClosure()); @@ -284,8 +284,8 @@ void PresentationServiceTestcase::TearDown() { base::RunLoop run_loop; - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&PresentationServiceTestcase::TearDownOnUIThread, base::Unretained(this)), run_loop.QuitClosure()); @@ -306,8 +306,8 @@ // `Unretained` is safe here, as `run_loop.Run()` blocks until // `PostTaskAndReply` calls the quit closure. base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&content::PresentationServiceImpl::Bind, base::Unretained(presentation_service_.get()), std::move(receiver)),
diff --git a/content/test/fuzzer/video_capture_host_mojolpm_fuzzer.cc b/content/test/fuzzer/video_capture_host_mojolpm_fuzzer.cc index 2d90d8f..61d1bea 100644 --- a/content/test/fuzzer/video_capture_host_mojolpm_fuzzer.cc +++ b/content/test/fuzzer/video_capture_host_mojolpm_fuzzer.cc
@@ -14,7 +14,6 @@ #include "base/i18n/icu_util.h" #include "base/no_destructor.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/test/test_timeouts.h" #include "base/threading/thread.h" @@ -25,6 +24,7 @@ #include "content/browser/renderer_host/media/video_capture_host.h" // nogncheck #include "content/browser/renderer_host/media/video_capture_manager.h" // nogncheck #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_content_client_initializer.h" @@ -297,13 +297,13 @@ case Action::kRunThread: { if (action.run_thread().id()) { base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - run_loop.QuitClosure()); + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); } else { base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTask(FROM_HERE, {content::BrowserThread::IO}, - run_loop.QuitClosure()); + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); } } break; @@ -334,8 +334,8 @@ void VideoCaptureHostTestcase::SetUp() { { base::RunLoop run_loop{base::RunLoop::Type::kNestableTasksAllowed}; - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&VideoCaptureHostTestcase::SetUpOnIOThreadFirst, base::Unretained(this)), run_loop.QuitClosure()); @@ -343,8 +343,8 @@ } { base::RunLoop run_loop{base::RunLoop::Type::kNestableTasksAllowed}; - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&VideoCaptureHostTestcase::SetUpOnUIThread, base::Unretained(this)), run_loop.QuitClosure()); @@ -352,8 +352,8 @@ } { base::RunLoop run_loop{base::RunLoop::Type::kNestableTasksAllowed}; - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&VideoCaptureHostTestcase::SetUpOnIOThreadSecond, base::Unretained(this)), run_loop.QuitClosure()); @@ -413,8 +413,8 @@ content::MediaDeviceSaltAndOrigin salt_and_origin; { base::RunLoop run_loop{base::RunLoop::Type::kNestableTasksAllowed}; - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&VideoCaptureHostTestcase::OpenSessionOnUIThread, base::Unretained(this), render_process_id, render_frame_id, base::Unretained(&salt_and_origin)), @@ -423,8 +423,8 @@ } { base::RunLoop run_loop{base::RunLoop::Type::kNestableTasksAllowed}; - base::PostTask( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&VideoCaptureHostTestcase::OpenSessionOnIOThread, base::Unretained(this), render_process_id, render_frame_id, requester_id, page_request_id, @@ -486,8 +486,8 @@ void VideoCaptureHostTestcase::TearDown() { { base::RunLoop run_loop{base::RunLoop::Type::kNestableTasksAllowed}; - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&VideoCaptureHostTestcase::TearDownOnIOThread, base::Unretained(this)), run_loop.QuitClosure()); @@ -495,8 +495,8 @@ } { base::RunLoop run_loop{base::RunLoop::Type::kNestableTasksAllowed}; - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&VideoCaptureHostTestcase::TearDownOnUIThread, base::Unretained(this)), run_loop.QuitClosure()); @@ -556,8 +556,8 @@ auto receiver = remote.BindNewPipeAndPassReceiver(); base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - base::PostTaskAndReply( - FROM_HERE, {content::BrowserThread::IO}, + content::GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::BindOnce(&content::VideoCaptureHost::Create, render_process_id, media_stream_manager_.get(), std::move(receiver)), run_loop.QuitClosure());
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 59dfb6f..7648e5e 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1608,6 +1608,7 @@ LANGUAGESETTINGSPRIVATE_SETLANGUAGEALWAYSTRANSLATESTATE = 1545, ACCESSIBILITY_PRIVATE_SHOWCONFIRMATIONDIALOG = 1546, AUTOTESTPRIVATE_INSTALLBOREALIS = 1547, + LANGUAGESETTINGSPRIVATE_SETTRANSLATETARGETLANGUAGE = 1548, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn index 52c6634..e70245b 100644 --- a/fuchsia/engine/BUILD.gn +++ b/fuchsia/engine/BUILD.gn
@@ -362,6 +362,7 @@ "browser/media_browsertest.cc", "browser/navigation_policy_browsertest.cc", "browser/theme_manager_browsertest.cc", + "browser/virtual_keyboard_browsertest.cc", ] # TODO(crbug.com/1157909): Move to the list above when the bug is fixed. @@ -388,6 +389,7 @@ "//testing/gmock", "//testing/gtest", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.input.virtualkeyboard", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", "//ui/gfx", "//ui/ozone",
diff --git a/fuchsia/engine/browser/frame_impl.h b/fuchsia/engine/browser/frame_impl.h index 429c3b50..fea7e90 100644 --- a/fuchsia/engine/browser/frame_impl.h +++ b/fuchsia/engine/browser/frame_impl.h
@@ -104,6 +104,9 @@ CastStreamingSessionClient* cast_streaming_session_client_for_test() { return cast_streaming_session_client_.get(); } + FrameWindowTreeHost* window_tree_host_for_test() { + return window_tree_host_.get(); + } // Enables explicit sites filtering and set the error page. If |error_page| is // empty, the default error page will be used.
diff --git a/fuchsia/engine/browser/virtual_keyboard_browsertest.cc b/fuchsia/engine/browser/virtual_keyboard_browsertest.cc new file mode 100644 index 0000000..6c646f95 --- /dev/null +++ b/fuchsia/engine/browser/virtual_keyboard_browsertest.cc
@@ -0,0 +1,376 @@ +// 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 <fuchsia/input/virtualkeyboard/cpp/fidl.h> +#include <lib/fit/function.h> +#include <lib/ui/scenic/cpp/view_ref_pair.h> +#include <lib/ui/scenic/cpp/view_token_pair.h> + +#include "base/callback.h" +#include "base/fuchsia/fuchsia_logging.h" +#include "base/fuchsia/scoped_service_binding.h" +#include "base/fuchsia/test_component_context_for_process.h" +#include "base/strings/stringprintf.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "fuchsia/base/frame_test_util.h" +#include "fuchsia/base/test_navigation_listener.h" +#include "fuchsia/engine/browser/frame_impl.h" +#include "fuchsia/engine/browser/frame_window_tree_host.h" +#include "fuchsia/engine/test/test_data.h" +#include "fuchsia/engine/test/web_engine_browser_test.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace virtualkeyboard = fuchsia::input::virtualkeyboard; + +namespace { + +const gfx::Rect kBounds = {1000, 1000}; +const gfx::Point kNoTarget = {999, 999}; + +constexpr char kInputFieldText[] = "input-text"; +constexpr char kInputFieldTel[] = "input-tel"; +constexpr char kInputFieldNumeric[] = "input-numeric"; +constexpr char kInputFieldUrl[] = "input-url"; +constexpr char kInputFieldEmail[] = "input-email"; +constexpr char kInputFieldDecimal[] = "input-decimal"; +constexpr char kInputFieldSearch[] = "input-search"; + +zx_handle_t GetKoidFromEventPair(const zx::eventpair& object) { + zx_info_handle_basic_t handle_info{}; + zx_status_t status = + object.get_info(ZX_INFO_HANDLE_BASIC, &handle_info, + sizeof(zx_info_handle_basic_t), nullptr, nullptr); + ZX_CHECK(status == ZX_OK, status) << "zx_object_get_info"; + return handle_info.koid; +} + +class MockVirtualKeyboardController : public virtualkeyboard::Controller { + public: + MockVirtualKeyboardController() : binding_(this) {} + ~MockVirtualKeyboardController() override {} + + MockVirtualKeyboardController(MockVirtualKeyboardController&) = delete; + MockVirtualKeyboardController operator=(MockVirtualKeyboardController&) = + delete; + + void Bind(fuchsia::ui::views::ViewRef view_ref, + virtualkeyboard::TextType text_type, + fidl::InterfaceRequest<fuchsia::input::virtualkeyboard::Controller> + controller_request) { + text_type_ = text_type; + view_ref_ = std::move(view_ref); + binding_.Bind(std::move(controller_request)); + } + + // Spins a RunLoop until the client calls WatchVisibility(). + void AwaitWatchAndRespondWith(bool is_visible) { + if (!watch_vis_callback_) { + base::RunLoop run_loop; + on_watch_visibility_ = run_loop.QuitClosure(); + run_loop.Run(); + ASSERT_TRUE(watch_vis_callback_); + } + + (*watch_vis_callback_)(is_visible); + watch_vis_callback_ = {}; + } + + const fuchsia::ui::views::ViewRef& view_ref() const { return view_ref_; } + virtualkeyboard::TextType text_type() const { return text_type_; } + + // virtualkeyboard::Controller implementation. + MOCK_METHOD0(RequestShow, void()); + MOCK_METHOD0(RequestHide, void()); + MOCK_METHOD1(SetTextType, void(virtualkeyboard::TextType text_type)); + + private: + // virtualkeyboard::Controller implementation. + void WatchVisibility( + virtualkeyboard::Controller::WatchVisibilityCallback callback) final { + watch_vis_callback_ = std::move(callback); + + if (on_watch_visibility_) + std::move(on_watch_visibility_).Run(); + } + + base::OnceClosure on_watch_visibility_; + base::Optional<virtualkeyboard::Controller::WatchVisibilityCallback> + watch_vis_callback_; + fuchsia::ui::views::ViewRef view_ref_; + virtualkeyboard::TextType text_type_; + fidl::Binding<fuchsia::input::virtualkeyboard::Controller> binding_; +}; + +// Services connection requests for MockVirtualKeyboardControllers. +class MockVirtualKeyboardControllerCreator + : public virtualkeyboard::ControllerCreator { + public: + explicit MockVirtualKeyboardControllerCreator( + base::TestComponentContextForProcess* component_context) + : binding_(component_context->additional_services(), this) {} + + ~MockVirtualKeyboardControllerCreator() override { + CHECK(!pending_controller_); + } + + MockVirtualKeyboardControllerCreator(MockVirtualKeyboardControllerCreator&) = + delete; + MockVirtualKeyboardControllerCreator operator=( + MockVirtualKeyboardControllerCreator&) = delete; + + // Returns an unbound MockVirtualKeyboardController, which will later be + // connected when |this| handles a call to the FIDL method Create(). + std::unique_ptr<MockVirtualKeyboardController> CreateController() { + DCHECK(!pending_controller_); + + auto controller = std::make_unique<MockVirtualKeyboardController>(); + pending_controller_ = controller.get(); + return controller; + } + + private: + // fuchsia::input::virtualkeyboard implementation. + void Create( + fuchsia::ui::views::ViewRef view_ref, + fuchsia::input::virtualkeyboard::TextType text_type, + fidl::InterfaceRequest<fuchsia::input::virtualkeyboard::Controller> + controller_request) final { + CHECK(pending_controller_); + pending_controller_->Bind(std::move(view_ref), text_type, + std::move(controller_request)); + pending_controller_ = nullptr; + } + + MockVirtualKeyboardController* pending_controller_ = nullptr; + base::ScopedServiceBinding<virtualkeyboard::ControllerCreator> binding_; +}; + +class VirtualKeyboardTest : public cr_fuchsia::WebEngineBrowserTest { + public: + VirtualKeyboardTest() { + set_test_server_root(base::FilePath(cr_fuchsia::kTestServerRoot)); + } + ~VirtualKeyboardTest() override = default; + + void SetUpOnMainThread() override { + cr_fuchsia::WebEngineBrowserTest::SetUpOnMainThread(); + ASSERT_TRUE(embedded_test_server()->Start()); + + component_context_.emplace( + base::TestComponentContextForProcess::InitialState::kCloneAll); + controller_creator_.emplace(&*component_context_); + controller_ = controller_creator_->CreateController(); + + frame_ = CreateFrame(&navigation_listener_); + frame_impl_ = context_impl()->GetFrameImplForTest(&frame_); + + // Navigate to the test page. + fuchsia::web::NavigationControllerPtr controller; + frame_->GetNavigationController(controller.NewRequest()); + const GURL test_url(embedded_test_server()->GetURL("/input_fields.html")); + EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse( + controller.get(), fuchsia::web::LoadUrlParams(), test_url.spec())); + navigation_listener_.RunUntilUrlEquals(test_url); + + // Simulate the creation of a Scenic View, except bypassing the actual + // construction of a Scenic PlatformWindow in favor of using an injected + // StubWindow. + scenic::ViewRefPair view_ref_pair = scenic::ViewRefPair::New(); + view_ref_ = std::move(view_ref_pair.view_ref); + fuchsia::ui::views::ViewRef view_ref_dup; + zx_status_t status = view_ref_.reference.duplicate(ZX_RIGHT_SAME_RIGHTS, + &view_ref_dup.reference); + ZX_CHECK(status == ZX_OK, status) << "zx_object_duplicate"; + + auto view_tokens = scenic::ViewTokenPair::New(); + frame_->CreateViewWithViewRef(std::move(view_tokens.view_token), + std::move(view_ref_pair.control_ref), + std::move(view_ref_dup)); + base::RunLoop().RunUntilIdle(); + frame_impl_->window_tree_host_for_test()->Show(); + + // Prepare the view for headless interaction by setting its focus state and + // size. + web_contents_ = frame_impl_->web_contents(); + content::RenderWidgetHostView* view = + web_contents_->GetMainFrame()->GetView(); + view->SetBounds(kBounds); + view->Focus(); + + controller_->AwaitWatchAndRespondWith(false); + + ASSERT_EQ(GetKoidFromEventPair(controller_->view_ref().reference), + GetKoidFromEventPair(view_ref_.reference)); + } + + void TearDownOnMainThread() override { + frame_.Unbind(); + base::RunLoop().RunUntilIdle(); + } + + gfx::Point GetCoordinatesOfInputField(base::StringPiece id) { + // Distance to click from the top/left extents of an input field. + constexpr int kInputFieldClickInset = 8; + + base::Optional<base::Value> result = cr_fuchsia::ExecuteJavaScript( + frame_.get(), + base::StringPrintf("getPointInsideText('%s')", id.data())); + CHECK(result); + + // Note that coordinates are floating point and must be retrieved as such + // from the Value, but we can cast them to integers and disregard the + // fractional value with no major consequences. + return gfx::Point(*result->FindDoublePath("x") + kInputFieldClickInset, + *result->FindDoublePath("y") + kInputFieldClickInset); + } + + protected: + // Used to publish fake virtual keyboard services for the InputMethod to use. + base::Optional<base::TestComponentContextForProcess> component_context_; + base::Optional<MockVirtualKeyboardControllerCreator> controller_creator_; + std::unique_ptr<MockVirtualKeyboardController> controller_; + + fuchsia::web::FramePtr frame_; + FrameImpl* frame_impl_ = nullptr; + content::WebContents* web_contents_ = nullptr; + cr_fuchsia::TestNavigationListener navigation_listener_; + fuchsia::ui::views::ViewRef view_ref_; +}; + +// Verifies that RequestShow() is invoked multiple times if the virtual +// keyboard service does not indicate that the keyboard is made visible. +IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, ShowAndHideCalledButIgnored) { + testing::InSequence s; + EXPECT_CALL(*controller_, RequestShow()).Times(2); + EXPECT_CALL(*controller_, RequestHide()); + base::RunLoop run_loop; + EXPECT_CALL(*controller_, RequestShow()) + .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); + + // Tap inside the text field. The IME should be summoned via a call to + // RequestShow(). + content::SimulateTapAt(web_contents_, + GetCoordinatesOfInputField(kInputFieldText)); + + // Change fields. RequestShow() should be called again, since the keyboard + // is not yet known to be visible. + content::SimulateTapAt(web_contents_, + GetCoordinatesOfInputField(kInputFieldNumeric)); + + // Tap outside the text field. The IME should be dismissed, which will result + // in a call to RequestHide(). + content::SimulateTapAt(web_contents_, kNoTarget); + + // Tap back on a text field. RequestShow should be called. + content::SimulateTapAt(web_contents_, + GetCoordinatesOfInputField(kInputFieldText)); + run_loop.Run(); +} + +// Verifies that RequestShow() is not called redundantly if the virtual +// keyboard is reported as visible. +IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, ShowAndHideWithVisibility) { + testing::InSequence s; + base::RunLoop on_show_run_loop; + EXPECT_CALL(*controller_, + SetTextType(virtualkeyboard::TextType::ALPHANUMERIC)); + EXPECT_CALL(*controller_, RequestShow()) + .WillOnce(testing::InvokeWithoutArgs( + [&on_show_run_loop]() { on_show_run_loop.Quit(); })); + EXPECT_CALL(*controller_, SetTextType(virtualkeyboard::TextType::NUMERIC)); + base::RunLoop on_hide_run_loop; + EXPECT_CALL(*controller_, RequestHide()) + .WillOnce(testing::InvokeWithoutArgs( + [&on_hide_run_loop]() { on_hide_run_loop.Quit(); })); + + // Give focus to an input field, which will result in RequestShow() being + // called. + content::SimulateTapAt(web_contents_, + GetCoordinatesOfInputField(kInputFieldText)); + on_show_run_loop.Run(); + + // Indicate that the virtual keyboard is now visible. + controller_->AwaitWatchAndRespondWith(true); + + // Tap on another text field. RequestShow should not be called a second time + // since the keyboard is already onscreen. + content::SimulateTapAt(web_contents_, + GetCoordinatesOfInputField(kInputFieldNumeric)); + base::RunLoop().RunUntilIdle(); + + content::SimulateTapAt(web_contents_, kNoTarget); + on_hide_run_loop.Run(); +} + +// Gives focus to a sequence of HTML <input> nodes with different InputModes, +// and verifies that the InputMode's FIDL equivalent is sent via SetTextType(). +IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, InputModeMappings) { + const std::vector<std::pair<base::StringPiece, virtualkeyboard::TextType>> + kInputTypeMappings = { + {kInputFieldText, virtualkeyboard::TextType::ALPHANUMERIC}, + {kInputFieldTel, virtualkeyboard::TextType::PHONE}, + {kInputFieldNumeric, virtualkeyboard::TextType::NUMERIC}, + {kInputFieldUrl, virtualkeyboard::TextType::ALPHANUMERIC}, + {kInputFieldEmail, virtualkeyboard::TextType::ALPHANUMERIC}, + {kInputFieldDecimal, virtualkeyboard::TextType::NUMERIC}, + {kInputFieldSearch, virtualkeyboard::TextType::ALPHANUMERIC}, + }; + + // Simulate like the keyboard is already shown, so that the test can focus on + // input type mappings without clutter from visibility management. + controller_->AwaitWatchAndRespondWith(true); + base::RunLoop().RunUntilIdle(); + + // GMock expectations must be set upfront, hence the redundant for-each loop. + for (const auto& field_type_pair : kInputTypeMappings) { + EXPECT_CALL(*controller_, SetTextType(field_type_pair.second)) + .RetiresOnSaturation(); + } + + base::RunLoop run_loop; + EXPECT_CALL(*controller_, RequestHide()) + .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); + + for (const auto& field_type_pair : kInputTypeMappings) { + content::SimulateTapAt(web_contents_, + GetCoordinatesOfInputField(field_type_pair.first)); + } + + // Dismiss the virtual keyboard and wait for RequestHide(). + content::SimulateTapAt(web_contents_, kNoTarget); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, Disconnection) { + testing::InSequence s; + base::RunLoop on_show_run_loop; + EXPECT_CALL(*controller_, + SetTextType(virtualkeyboard::TextType::ALPHANUMERIC)); + EXPECT_CALL(*controller_, RequestShow()) + .WillOnce(testing::InvokeWithoutArgs( + [&on_show_run_loop]() { on_show_run_loop.Quit(); })); + + // Tapping inside the text field should show the IME and signal RequestShow. + content::SimulateTapAt(web_contents_, + GetCoordinatesOfInputField(kInputFieldText)); + on_show_run_loop.Run(); + + controller_->AwaitWatchAndRespondWith(true); + base::RunLoop().RunUntilIdle(); + + // Disconnect the FIDL service. + controller_.reset(); + base::RunLoop().RunUntilIdle(); + + // Focus on another text field, then defocus. Nothing should crash. + content::SimulateTapAt(web_contents_, + GetCoordinatesOfInputField(kInputFieldNumeric)); + content::SimulateTapAt(web_contents_, kNoTarget); +} + +} // namespace
diff --git a/fuchsia/engine/test/data/input_fields.html b/fuchsia/engine/test/data/input_fields.html new file mode 100644 index 0000000..8a47744 --- /dev/null +++ b/fuchsia/engine/test/data/input_fields.html
@@ -0,0 +1,19 @@ +<html> + <body> + <input id="input-text" /> + <input id="input-tel" inputmode="tel" /> + <input id="input-numeric" inputmode="numeric"/> + <input id="input-url" inputmode="url"/> + <input id="input-email" inputmode="email"/> + <input id="input-decimal" inputmode="decimal"/> + <input id="input-search" inputmode="search"/> + + <script> + function getPointInsideText(id) { + var rect = document.getElementById(id).getBoundingClientRect(); + return { 'x': rect.left + 8, 'y': rect.top + 8 }; + } + </script> + </body> +</html> +
diff --git a/fuchsia/runners/cast/cast_runner.cmx b/fuchsia/runners/cast/cast_runner.cmx index 4b64d37..892eaa6 100644 --- a/fuchsia/runners/cast/cast_runner.cmx +++ b/fuchsia/runners/cast/cast_runner.cmx
@@ -11,6 +11,7 @@ "fuchsia.device.NameProvider", "fuchsia.feedback.CrashReportingProductRegister", "fuchsia.fonts.Provider", + "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink", "fuchsia.media.Audio", @@ -25,8 +26,6 @@ "fuchsia.process.Launcher", "fuchsia.settings.Display", "fuchsia.sysmem.Allocator", - "fuchsia.ui.input.ImeService", - "fuchsia.ui.input.ImeVisibilityService", "fuchsia.ui.scenic.Scenic", "fuchsia.vulkan.loader.Loader", "fuchsia.web.ContextProvider"
diff --git a/fuchsia/runners/web/web_runner.cmx b/fuchsia/runners/web/web_runner.cmx index 36fc69d..2e1fb00c 100644 --- a/fuchsia/runners/web/web_runner.cmx +++ b/fuchsia/runners/web/web_runner.cmx
@@ -8,6 +8,7 @@ "fuchsia.camera3.DeviceWatcher", "fuchsia.device.NameProvider", "fuchsia.fonts.Provider", + "fuchsia.input.virtualkeyboard.ControllerCreator", "fuchsia.intl.PropertyProvider", "fuchsia.logger.LogSink", "fuchsia.media.Audio",
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index 098f5b20..aa5f7b3 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg
@@ -294,6 +294,10 @@ includable_only: true } builders { + name: "chromium/try/android-web-platform-pie-x86-fyi-rel" + includable_only: true + } + builders { name: "chromium/try/android-weblayer-pie-x86-rel-tests" includable_only: true }
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index d8c5b542..e846e1f 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -11421,64 +11421,6 @@ } } builders { - name: "Mac10.13 Tests (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "Mac10.14 Tests" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -12522,6 +12464,64 @@ } } builders { + name: "TSAN Release (runsc-exp) (reclient)" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "luciexe" + } + properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$build/reclient\":{\"instance\":\"rbe-chromium-gvisor-shadow\",\"metrics_project\":\"chromium-reclient-metrics\"},\"$kitchen\":{\"devshell\":true,\"emulate_gce\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + execution_timeout_secs: 36000 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "chromium.resultdb.result_sink" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.gtests_local" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.junit_tests" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "ToTAndroid" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -33287,6 +33287,71 @@ } } builders { + name: "android-web-platform-pie-x86-fyi-rel" + swarming_host: "chromium-swarm.appspot.com" + swarming_tags: "vpython:native-python-wrapper" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-16.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" + cipd_version: "refs/heads/master" + cmd: "recipes" + } + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium.resultdb.result_sink" + value: 100 + } + experiments { + key: "chromium.resultdb.result_sink.junit_tests" + value: 100 + } + experiments { + key: "luci.use_realms" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "luci-resultdb" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "android-weblayer-pie-x86-rel-tests" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index 847cf21..307fa27 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -181,11 +181,6 @@ short_name: "bld" } builders { - name: "buildbucket/luci.chromium.ci/Mac10.13 Tests (dbg)" - category: "chromium.mac|debug" - short_name: "13" - } - builders { name: "buildbucket/luci.chromium.ci/Mac10.15 Tests (dbg)" category: "chromium.mac|debug" short_name: "15" @@ -886,11 +881,6 @@ short_name: "bld" } builders { - name: "buildbucket/luci.chromium.ci/Mac10.13 Tests (dbg)" - category: "chromium.mac|debug" - short_name: "13" - } - builders { name: "buildbucket/luci.chromium.ci/Mac10.15 Tests (dbg)" category: "chromium.mac|debug" short_name: "15" @@ -5908,6 +5898,11 @@ short_name: "rre" } builders { + name: "buildbucket/luci.chromium.ci/TSAN Release (runsc-exp) (reclient)" + category: "linux tsan" + short_name: "rre" + } + builders { name: "buildbucket/luci.chromium.ci/linux-upload-perfetto" category: "perfetto" short_name: "lnx" @@ -8385,11 +8380,6 @@ short_name: "bld" } builders { - name: "buildbucket/luci.chromium.ci/Mac10.13 Tests (dbg)" - category: "debug" - short_name: "13" - } - builders { name: "buildbucket/luci.chromium.ci/Mac10.15 Tests (dbg)" category: "debug" short_name: "15" @@ -12246,6 +12236,9 @@ name: "buildbucket/luci.chromium.try/android-pie-x86-rel" } builders { + name: "buildbucket/luci.chromium.try/android-web-platform-pie-x86-fyi-rel" + } + builders { name: "buildbucket/luci.chromium.try/android-weblayer-pie-x86-rel-tests" } builders { @@ -13225,6 +13218,9 @@ name: "buildbucket/luci.chromium.try/android-pie-x86-rel" } builders { + name: "buildbucket/luci.chromium.try/android-web-platform-pie-x86-fyi-rel" + } + builders { name: "buildbucket/luci.chromium.try/android-weblayer-pie-x86-rel-tests" } builders {
diff --git a/infra/config/generated/luci-notify.cfg b/infra/config/generated/luci-notify.cfg index ffdf078..3f92e23 100644 --- a/infra/config/generated/luci-notify.cfg +++ b/infra/config/generated/luci-notify.cfg
@@ -1572,24 +1572,6 @@ } builders { bucket: "ci" - name: "Mac10.13 Tests (dbg)" - } - tree_closers { - tree_status_host: "chromium-status.appspot.com" - failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b" - } -} -notifiers { - notifications { - on_occurrence: FAILURE - failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b" - email { - rotation_urls: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-build-sheriff" - } - template: "tree_closure_email_template" - } - builders { - bucket: "ci" name: "Mac10.14 Tests" } tree_closers {
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index 03094f6..faecf86d 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -2582,20 +2582,6 @@ } } job { - id: "Mac10.13 Tests (dbg)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "Mac10.13 Tests (dbg)" - } -} -job { id: "Mac10.14 Tests" realm: "ci" acls { @@ -2824,6 +2810,20 @@ } } job { + id: "TSAN Release (runsc-exp) (reclient)" + realm: "ci" + acl_sets: "ci" + triggering_policy { + kind: GREEDY_BATCHING + max_concurrent_invocations: 3 + } + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "TSAN Release (runsc-exp) (reclient)" + } +} +job { id: "ToTAndroid" realm: "ci" acl_sets: "ci" @@ -6855,6 +6855,7 @@ triggers: "TSAN Debug (reclient)" triggers: "TSAN Release" triggers: "TSAN Release (reclient)" + triggers: "TSAN Release (runsc-exp) (reclient)" triggers: "ToTAndroid" triggers: "ToTAndroid (dbg)" triggers: "ToTAndroid x64"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index 633734c..cac63c59 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -3591,6 +3591,22 @@ ) ci.fyi_builder( + name = "TSAN Release (runsc-exp) (reclient)", + console_view_entry = consoles.console_view_entry( + category = "linux tsan", + short_name = "rre", + ), + triggering_policy = scheduler.greedy_batching( + max_concurrent_invocations = 3, + ), + goma_backend = None, + reclient_instance = "rbe-chromium-gvisor-shadow", + configure_kitchen = True, + kitchen_emulate_gce = True, + os = os.LINUX_DEFAULT, +) + +ci.fyi_builder( name = "ASAN Debug (reclient)", console_view_entry = consoles.console_view_entry( category = "linux asan", @@ -5284,19 +5300,6 @@ ) ci.thin_tester( - name = "Mac10.13 Tests (dbg)", - branch_selector = branches.STANDARD_MILESTONE, - builder_group = "chromium.mac", - console_view_entry = consoles.console_view_entry( - category = "debug", - short_name = "13", - ), - cq_mirrors_console_view = "mirrors", - main_console_view = "main", - triggered_by = ["ci/Mac Builder (dbg)"], -) - -ci.thin_tester( name = "Mac10.15 Tests (dbg)", branch_selector = branches.STANDARD_MILESTONE, builder_group = "chromium.mac",
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 567eb29..0612d7e 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -488,6 +488,10 @@ ) try_.chromium_android_builder( + name = "android-web-platform-pie-x86-fyi-rel", +) + +try_.chromium_android_builder( name = "android-weblayer-pie-x86-rel-tests", )
diff --git a/ios/chrome/browser/autofill/form_structure_browsertest.mm b/ios/chrome/browser/autofill/form_structure_browsertest.mm index a5d398c9..8e17c6f8 100644 --- a/ios/chrome/browser/autofill/form_structure_browsertest.mm +++ b/ios/chrome/browser/autofill/form_structure_browsertest.mm
@@ -18,6 +18,7 @@ #include "components/autofill/core/browser/data_driven_test.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/common/autofill_features.h" +#include "components/autofill/core/common/autofill_payments_features.h" #include "components/autofill/core/common/unique_ids.h" #import "components/autofill/ios/browser/autofill_agent.h" #include "components/autofill/ios/browser/autofill_driver_ios.h" @@ -146,7 +147,9 @@ // TODO(crbug/1165780): Remove once shared labels are launched. autofill::features::kAutofillEnableSupportForParsingWithSharedLabels, // TODO(crbug.com/1150895) Remove once launched. - autofill::features::kAutofillParsingPatternsLanguageDetection}, + autofill::features::kAutofillParsingPatternsLanguageDetection, + // TODO(crbug.com/1190334): Remove once launched. + autofill::features::kAutofillParseMerchantPromoCodeFields}, // Disabled {}); }
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 49eea91..0acb823 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -707,6 +707,12 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(kDefaultPromoTailored, kDefaultPromoTailoredVariations, "DefaultPromoTailored")}, + {"autofill-parse-merchant-promo-code-fields", + flag_descriptions::kAutofillParseMerchantPromoCodeFieldsName, + flag_descriptions::kAutofillParseMerchantPromoCodeFieldsDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillParseMerchantPromoCodeFields)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 5ad93c3..5beb13ca 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -34,6 +34,12 @@ "Delay between the different fields of a form being autofilled. In " "milliseconds."; +const char kAutofillParseMerchantPromoCodeFieldsName[] = + "Parse promo code fields in forms"; +const char kAutofillParseMerchantPromoCodeFieldsDescription[] = + "When enabled, Autofill will attempt to find merchant promo/coupon/gift " + "code fields when parsing forms."; + const char kAutofillPruneSuggestionsName[] = "Autofill Prune Suggestions"; const char kAutofillPruneSuggestionsDescription[] = "Further limits the number of suggestions in the Autofill dropdown.";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index d1edc4a..dcdc22a 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -27,6 +27,10 @@ extern const char kAutofillIOSDelayBetweenFieldsName[]; extern const char kAutofillIOSDelayBetweenFieldsDescription[]; +// Title and description for the flag to parse promo code fields in Autofill. +extern const char kAutofillParseMerchantPromoCodeFieldsName[]; +extern const char kAutofillParseMerchantPromoCodeFieldsDescription[]; + // Title and description for the flag that controls whether the maximum number // of Autofill suggestions shown is pruned. extern const char kAutofillPruneSuggestionsName[];
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm index c1e8337e..d6edba2 100644 --- a/ios/chrome/browser/passwords/password_controller.mm +++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -177,10 +177,11 @@ _webStateObserverBridge = std::make_unique<web::WebStateObserverBridge>(self); _webState->AddObserver(_webStateObserverBridge.get()); - if (passwordManagerClient) + if (passwordManagerClient) { _passwordManagerClient = std::move(passwordManagerClient); - else + } else { _passwordManagerClient.reset(new IOSChromePasswordManagerClient(self)); + } _passwordManager.reset(new PasswordManager(_passwordManagerClient.get())); PasswordFormHelper* formHelper = @@ -306,8 +307,9 @@ // Shows auto sign-in notification and schedules hiding it after 3 seconds. // TODO(crbug.com/435048): Animate appearance. - (void)showAutosigninNotification:(std::unique_ptr<PasswordForm>)formSignedIn { - if (!_webState) + if (!_webState) { return; + } // If a notification is already being displayed, hides the old one, then shows // the new one. @@ -421,14 +423,15 @@ - (void)showInfoBarForForm:(std::unique_ptr<PasswordFormManagerForUI>)form infoBarType:(PasswordInfoBarType)type manual:(BOOL)manual { - if (!_webState) + if (!_webState) { return; + } bool isSyncUser = false; if (self.browserState) { - syncer::SyncService* sync_service = + syncer::SyncService* syncService = ProfileSyncServiceFactory::GetForBrowserState(self.browserState); - isSyncUser = password_bubble_experiment::IsSmartLockUser(sync_service); + isSyncUser = password_bubble_experiment::IsSmartLockUser(syncService); } infobars::InfoBarManager* infoBarManager = InfoBarManagerImpl::FromWebState(_webState); @@ -449,18 +452,18 @@ std::unique_ptr<InfoBarIOS> infobar; // If manual save, skip showing banner. - bool skip_banner = manual; + bool skipBanner = manual; if (IsInfobarOverlayUIEnabled()) { infobar = std::make_unique<InfoBarIOS>( InfobarType::kInfobarTypePasswordSave, std::move(delegate), - skip_banner); + skipBanner); } else { InfobarPasswordCoordinator* coordinator = [[InfobarPasswordCoordinator alloc] initWithInfoBarDelegate:delegate.get() type:InfobarType::kInfobarTypePasswordSave]; infobar = std::make_unique<InfoBarIOS>( - coordinator, std::move(delegate), skip_banner); + coordinator, std::move(delegate), skipBanner); } infoBarManager->AddInfoBar(std::move(infobar), /*replace_existing=*/true);
diff --git a/ios/chrome/browser/sync/device_info_sync_service_factory.mm b/ios/chrome/browser/sync/device_info_sync_service_factory.mm index ff0d319..6ab4ec19 100644 --- a/ios/chrome/browser/sync/device_info_sync_service_factory.mm +++ b/ios/chrome/browser/sync/device_info_sync_service_factory.mm
@@ -58,6 +58,12 @@ } // syncer::DeviceInfoSyncClient: + base::Optional<syncer::DeviceInfo::PhoneAsASecurityKeyInfo> + GetPhoneAsASecurityKeyInfo() const override { + return base::nullopt; + } + + // syncer::DeviceInfoSyncClient: base::Optional<std::string> GetFCMRegistrationToken() const override { if (sync_invalidations_service_) { return sync_invalidations_service_->GetFCMRegistrationToken();
diff --git a/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm index 08a7849..7009891 100644 --- a/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm +++ b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm
@@ -66,6 +66,9 @@ {"unknown", IDS_POLICY_UNKNOWN}, {"unset", IDS_POLICY_UNSET}, {"value", IDS_POLICY_LABEL_VALUE}, + {"sourceDefault", IDS_POLICY_SOURCE_DEFAULT}, + {"loadPoliciesDone", IDS_POLICY_LOAD_POLICIES_DONE}, + {"loadingPolicies", IDS_POLICY_LOADING_POLICIES}, }; source->AddLocalizedStrings(kStrings); source->AddLocalizedStrings(policy::kPolicySources);
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 index c60774b..4439ad5 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -d1b589801d02daf48eac14032e2211ad46ecf286 \ No newline at end of file +d3a45e75f6a1386a188fc7ce7ffd9615aea0c2fb \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 index e4e9730..57921d8c 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -298dbddeb4ef163b284f8bdd1646305d9dedd00e \ No newline at end of file +93b4c46ef4fefd3be94ee6e911973e6586a7a9b8 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 index 338de5c..c79c4c6e 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -b81f9ee455d2e572e80fdb886e432174e8a0395f \ No newline at end of file +97261f757ae9b73d81140fd48cb639822ed40e3e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 index 455a237..d3225bcb 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -fade884d603187653a3495df8ba1357f7ced20c3 \ No newline at end of file +18e9faec63fc193ff4f4ed9c3a5906b15316b2ad \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 index 4e16174..5804018 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -e358abc6aaae2bca8b11f73b03c4b5e30e29e018 \ No newline at end of file +e99fc23110e2e6417c344084f07989f858909a04 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 index e66452a..88efb296 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -de79bb3bcaf64ce5e5b28d73061ba4e51e4d7792 \ No newline at end of file +60ad3baf017e23780cfb6bad4c007b4b7495e46c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 index cd37b467..1ff1217 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -32007a8c2791124beba6bf8f909c240e20518dca \ No newline at end of file +d38d3f26c9d207310888a24118fbfa338aae1c46 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 index 30cb616a..9844510a 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -b1a155d7c0808324a23a27674343018a5a31ff20 \ No newline at end of file +aef9d7a08fddfb1dd6177f844b877f9c9444e0ab \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 index a4d7257..744b9f1 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -1143320ac8f8bf5645236cb98a5335c228055cd4 \ No newline at end of file +ee9a636b9e7505b90fddf0a2730505808d5ffc34 \ No newline at end of file
diff --git a/ios/web_view/internal/sync/web_view_device_info_sync_service_factory.mm b/ios/web_view/internal/sync/web_view_device_info_sync_service_factory.mm index d5afc329..b32c11c98 100644 --- a/ios/web_view/internal/sync/web_view_device_info_sync_service_factory.mm +++ b/ios/web_view/internal/sync/web_view_device_info_sync_service_factory.mm
@@ -73,6 +73,11 @@ return syncer::ModelTypeSet(); } + base::Optional<syncer::DeviceInfo::PhoneAsASecurityKeyInfo> + GetPhoneAsASecurityKeyInfo() const override { + return base::nullopt; + } + private: PrefService* const prefs_; syncer::SyncInvalidationsService* const sync_invalidations_service_;
diff --git a/ios/web_view/internal/translate/cwv_translation_controller_unittest.mm b/ios/web_view/internal/translate/cwv_translation_controller_unittest.mm index 063e3d7..7d7ef8f3 100644 --- a/ios/web_view/internal/translate/cwv_translation_controller_unittest.mm +++ b/ios/web_view/internal/translate/cwv_translation_controller_unittest.mm
@@ -107,7 +107,7 @@ pref_service_.registry()->RegisterDictionaryPref( translate::TranslatePrefs::kPrefNeverPromptSitesWithTime); pref_service_.registry()->RegisterDictionaryPref( - translate::TranslatePrefs::kPrefAlwaysTranslateLists); + prefs::kPrefAlwaysTranslateList); pref_service_.registry()->RegisterDictionaryPref( translate::TranslatePrefs::kPrefTranslateDeniedCount); pref_service_.registry()->RegisterDictionaryPref(
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java index a7cfe41..03a451ac 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
@@ -125,14 +125,18 @@ } /** - * Return true if and only if name is a software codec. - * @param name The codec name, e.g. from MediaCodecInfo.getName(). + * Return true if and only if info is a software codec. */ - public static boolean isSoftwareCodec(String name) { + private static boolean isSoftwareCodec(MediaCodecInfo info) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) return !info.isHardwareAccelerated(); + + String name = info.getName().toLowerCase(Locale.ROOT); // This is taken from libstagefright/OMXCodec.cpp for pre codec2. - if (name.startsWith("OMX.google.")) return true; - // Codec2 names sw decoders this way. See hardware/google/av/codec2/vndk/C2Store.cpp . - if (name.startsWith("c2.google.")) return true; + if (name.startsWith("omx.google.")) return true; + + // Codec2 names sw decoders this way. + // See hardware/google/av/codec2/vndk/C2Store.cpp. + if (name.startsWith("c2.google.") || name.startsWith("c2.android.")) return true; return false; } @@ -153,7 +157,7 @@ info.isEncoder() ? MediaCodecDirection.ENCODER : MediaCodecDirection.DECODER; if (codecDirection != direction) continue; - if (requireSoftwareCodec && !isSoftwareCodec(info.getName())) continue; + if (requireSoftwareCodec && !isSoftwareCodec(info)) continue; for (String supportedType : info.getSupportedTypes()) { if (supportedType.equalsIgnoreCase(mime)) return info.getName(); @@ -626,7 +630,7 @@ private static @Nullable @HWEncoder Integer findHWEncoder(String mime) { MediaCodecListHelper codecListHelper = new MediaCodecListHelper(); for (MediaCodecInfo info : codecListHelper) { - if (!info.isEncoder() || isSoftwareCodec(info.getName())) continue; + if (!info.isEncoder() || isSoftwareCodec(info)) continue; String encoderName = null; for (String mimeType : info.getSupportedTypes()) {
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 1f1b38ac..b0c5ad73 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -475,7 +475,7 @@ // Enable VA-API hardware decode acceleration for AV1. const base::Feature kVaapiAV1Decoder{"VaapiAV1Decoder", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enable VA-API hardware low power encoder for all codecs on intel Gen9x gpu. const base::Feature kVaapiLowPowerEncoderGen9x{
diff --git a/media/gpu/android/codec_allocator.cc b/media/gpu/android/codec_allocator.cc index d1c271e..af534db 100644 --- a/media/gpu/android/codec_allocator.cc +++ b/media/gpu/android/codec_allocator.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <memory> +#include "base/android/build_info.h" #include "base/callback_helpers.h" #include "base/logging.h" #include "base/task/post_task.h" @@ -100,7 +101,11 @@ // If we're still allowed to pick any type we want, then limit to software for // low resolution. https://crbug.com/1166833 - if (codec_config->codec_type == CodecType::kAny && + // Software decoders on Lollipop refuse to decode media that played + // everywhere else, so let's not force it. https://crbug.com/1175322 + bool lollipop = base::android::BuildInfo::GetInstance()->sdk_int() == + base::android::SDK_VERSION_LOLLIPOP; + if (!lollipop && codec_config->codec_type == CodecType::kAny && (codec_config->initial_expected_coded_size.width() < kMinHardwareResolution.width() || codec_config->initial_expected_coded_size.height() <
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni index 089e269..147a882 100644 --- a/mojo/public/tools/bindings/mojom.gni +++ b/mojo/public/tools/bindings/mojom.gni
@@ -110,17 +110,6 @@ # The path to a file whose contents can be used as the basis for a message # ID scrambling salt. mojom_message_id_salt_path = "//chrome/VERSION" - - # The path to a file whose contents will be concatenated to the contents of - # the file at |mojom_message_id_salt_path| to form a complete salt for - # message ID scrambling. May be the empty string, in which case the contents - # of the above file alone are used as the complete salt. - if (is_chrome_branded) { - mojom_message_id_salt_suffix_path = - "//mojo/internal/chrome-message-id-salt-suffix" - } else { - mojom_message_id_salt_suffix_path = "" - } } assert(mojom_message_id_salt_path != "") @@ -129,14 +118,6 @@ rebase_path(mojom_message_id_salt_path, root_build_dir), ] message_scrambling_inputs = [ mojom_message_id_salt_path ] - - if (mojom_message_id_salt_suffix_path != "") { - message_scrambling_args += [ - "--scrambled_message_id_salt_path", - rebase_path(mojom_message_id_salt_suffix_path, root_build_dir), - ] - message_scrambling_inputs += [ mojom_message_id_salt_suffix_path ] - } } else { message_scrambling_args = [] message_scrambling_inputs = []
diff --git a/net/base/escape.cc b/net/base/escape.cc index 88f9dc9..552a86b0 100644 --- a/net/base/escape.cc +++ b/net/base/escape.cc
@@ -84,9 +84,10 @@ } // Convert |input| string to a form that will not be interpreted as HTML. -template <class str> -str EscapeForHTMLImpl(base::BasicStringPiece<str> input) { - str result; +template <class CharT> +std::basic_string<CharT> EscapeForHTMLImpl( + base::BasicStringPiece<CharT> input) { + std::basic_string<CharT> result; result.reserve(input.size()); // Optimize for no escaping. for (auto c : input) {
diff --git a/net/base/registry_controlled_domains/registry_controlled_domain.cc b/net/base/registry_controlled_domains/registry_controlled_domain.cc index 0c44e8b7..6bd1d46 100644 --- a/net/base/registry_controlled_domains/registry_controlled_domain.cc +++ b/net/base/registry_controlled_domains/registry_controlled_domain.cc
@@ -226,10 +226,9 @@ } // Backend for PermissiveGetHostRegistryLength that handles both UTF-8 and -// UTF-16 input. The template type is the std::string type to use (it makes the -// typedefs easier than using the character type). -template <typename Str> -size_t DoPermissiveGetHostRegistryLength(base::BasicStringPiece<Str> host, +// UTF-16 input. +template <typename CharT> +size_t DoPermissiveGetHostRegistryLength(base::BasicStringPiece<CharT> host, UnknownRegistryFilter unknown_filter, PrivateRegistryFilter private_filter) { std::string canonical_host; // Do not modify outside of canon_output. @@ -445,15 +444,15 @@ size_t PermissiveGetHostRegistryLength(base::StringPiece host, UnknownRegistryFilter unknown_filter, PrivateRegistryFilter private_filter) { - return DoPermissiveGetHostRegistryLength<std::string>(host, unknown_filter, - private_filter); + return DoPermissiveGetHostRegistryLength(host, unknown_filter, + private_filter); } size_t PermissiveGetHostRegistryLength(base::StringPiece16 host, UnknownRegistryFilter unknown_filter, PrivateRegistryFilter private_filter) { - return DoPermissiveGetHostRegistryLength<std::u16string>(host, unknown_filter, - private_filter); + return DoPermissiveGetHostRegistryLength(host, unknown_filter, + private_filter); } void SetFindDomainGraph() {
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index 9ca07eba..e2f966c 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -1502,7 +1502,6 @@ { "name": "annevankesteren.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "annevankesteren.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "annevankesteren.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "barslecht.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "barslecht.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "blessnet.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cloudstoragemaus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -3674,7 +3673,6 @@ { "name": "bettrlifeapp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "billninja.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bionicspirit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "blackburn.link", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "blechschmidt.saarland", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bugginslab.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bwcscorecard.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -4475,7 +4473,6 @@ { "name": "b3orion.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bandrcrafts.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "beaglewatch.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "bermeitinger.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bettween.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bike-shack.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bildermachr.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -8105,7 +8102,6 @@ { "name": "britishscienceweek.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "britzer-toner.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "broken-oak.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "bta.lv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "btcdlc.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bubblegumblog.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "buchheld.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -8593,7 +8589,6 @@ { "name": "gee.is", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "geli-graphics.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "gemeentemolenwaard.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "genyhitch.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "georgesonarthurs.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "georgmayer.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "geoscan.aero", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -9318,7 +9313,6 @@ { "name": "performous.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "perspectivum.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pet-nsk.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "petpost.co.nz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pewboards.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pfarchimedes-pensioen123.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pgpm.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -13686,7 +13680,6 @@ { "name": "d0xq.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "clara-baumert.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dcepler.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "cozyeggdesigns.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "darkishgreen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cyberlab.kiev.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cryptophobia.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -16452,7 +16445,6 @@ { "name": "bedlingtonterrier.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ashlane-cottages.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "atraining.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "becubed.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "atelier-rk.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "autoentrepreneurinfo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bankbranchlocator.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -16597,7 +16589,6 @@ { "name": "bypassed.world", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bypassed.works", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bvexplained.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "cavalierkingcharlesspaniel.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bunbomenu.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "c-path.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "aoku3d.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -20197,7 +20188,6 @@ { "name": "raulrivero.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rainville.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "psychiatrie-betreuung.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "reallyreally.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "providerlijst.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "redhorsemountainranch.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "phototravel.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -21271,7 +21261,6 @@ { "name": "hukkatavara.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hypothes.is", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ibcmed.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "icecars.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "iclinic.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "iconomi.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "icpc.pp.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -22812,7 +22801,6 @@ { "name": "entactogen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "entryboss.cc", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "entrypoint.sh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "enviroprobasements.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "eocservices.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "epicmc.games", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "epolitiker.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -23177,7 +23165,6 @@ { "name": "hedweb.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hefengautoparts.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "heidisheroes.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "hekeki.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hellofilters.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hellothought.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "helsingfors.guide", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -23621,7 +23608,6 @@ { "name": "liskgdt.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "listage.ovh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "littlewatcher.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "liujunyang.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "livedesign24.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "liyin.date", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ljason.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -24782,7 +24768,6 @@ { "name": "tdsb.ga", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tdsb.gq", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tdsb.ml", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "teambition.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "teamnissannorthparts.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tech-blogger.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "techbrown.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -25907,7 +25892,6 @@ { "name": "craftyphotons.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "coup-dun-soir.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "costa-rica-reisen.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "cultivo.bio", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cydetec.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "curvesandwords.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "coroasdefloresonline.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -27301,7 +27285,6 @@ { "name": "palabr.as", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "openiocdb.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ninjaspiders.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "pasadenasandwichcompany.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "padrepio.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "papersmart.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "paperwritinghelp.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -28180,7 +28163,6 @@ { "name": "vermuetje.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "veritafineviolins.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "viktorprevaric.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "velotyretz.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "vera.bg", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "v789xl.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "verzick.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -31265,7 +31247,6 @@ { "name": "passionatehorsemanship.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pastorsuico.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "paul-bronski.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "pawsomebox.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "payssaintgilles.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "penticton.photography", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "peoplelikemeapp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -34723,7 +34704,6 @@ { "name": "newburyparkelectrical.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "newmarketbouncycastlehire.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "newsa2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "nfir.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ninaforever.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "njguardtraining.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "noc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -38980,7 +38960,6 @@ { "name": "mauerwerkstag.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mcpro.games", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "medhy.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mega-byte.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meh.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meklon.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "membershipservices.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -39075,7 +39054,6 @@ { "name": "pattonfanatic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pavelstriz.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pb-design.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pbcomp.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pdxtowncar.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peaceloveandlabor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pelletizermill.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -44035,7 +44013,6 @@ { "name": "rothe.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "route-wird-berechnet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rritv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "s0laris.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sacprincesse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "safestore.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "samdev.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -44646,7 +44623,6 @@ { "name": "mkk.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mksdarchitects.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mocloud.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mococo.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "moeking.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "monkeybusiness.agency", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "morbiceramicindustry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -45254,7 +45230,6 @@ { "name": "gurpusmaximus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hackereyes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hacksecu.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "hamiltonmedical.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hansonian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hapheemraadssingel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hapsana.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -45728,7 +45703,6 @@ { "name": "voirodaisuki.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vpsvz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wangtanzhang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "wanybug.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wbudd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wby.gd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webdevxp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -48272,7 +48246,6 @@ { "name": "chamicro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chargedmonkey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "charisma.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "charmanterelefant.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chefwear.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chenzhipeng.com.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "chibr.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -51236,7 +51209,6 @@ { "name": "academkin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "acklandstainless.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "actioncleaningnd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "actualidadgadget.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "actualidadkd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "addictionresource.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "advanced-fleet-services.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -53014,7 +52986,6 @@ { "name": "888funcity.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "a-invest.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "acl.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "acpcoils.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "acscbasket.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "afwd.international", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ahawkesrealtors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -55302,7 +55273,6 @@ { "name": "skyfone.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "skyger.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smaltimentorifiuti.livorno.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "smartphones-baratos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smartweb.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sn0int.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "snabbare-dator.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -55333,7 +55303,6 @@ { "name": "sqsd.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ssl24.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "stadtkapelle-oehringen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "stainternational.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "stang.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "starport.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "startanull.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -55376,7 +55345,6 @@ { "name": "szepsegbennedrejlik.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "t-m.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "t9i.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tabletsbaratasya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "taherian.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "taron.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tasadordecoches.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -57341,7 +57309,6 @@ { "name": "inoxdesign.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "inspiratienodig.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "integrata.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "internetgardener.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "intropickup.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ipso.paris", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "irismq.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -57669,7 +57636,6 @@ { "name": "performancegate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "permaseal.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peruvianphotography.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "peterboweycomputerservices.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "petto.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "phonenumber-info.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pickupenc.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -59853,7 +59819,6 @@ { "name": "baleen.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "balmeo.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "barsgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "beckyhirstconsulting.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bentinata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bighouse-events.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bjoernengel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -60140,7 +60105,6 @@ { "name": "uitvaartzorg-heerenveen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "uitvaartzorgzuidwestfriesland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "uleenucks.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ulotnefoto.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "um-sachsen-pictures.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "unblocked.cx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "unblocked.llc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -60720,7 +60684,6 @@ { "name": "felixkaaman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fikriwildannugraha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fiskelures.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "fleischmann.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fleursdujour.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "florlola.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "frontletter.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -60787,7 +60750,6 @@ { "name": "magicsms.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "makropa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mara-martinez.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "marcobicca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mcjackk77.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mdtorelli.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meidens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -62045,7 +62007,6 @@ { "name": "4smart.house", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "54lsj.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "595380.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "5conejos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "5in.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "657660.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "657990.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -64082,7 +64043,6 @@ { "name": "venstar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vibgyyor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vip380.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "visitorguard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vivaio.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "vwh-kunden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wancai666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -65091,7 +65051,6 @@ { "name": "argecord.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arterydb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arthritisrheumaticdiseases.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "auburnmedicalservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "authcom.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "auto-none.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "avinilo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -68288,7 +68247,6 @@ { "name": "financecontrol.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "floridawaterapparel.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "forsaleinedmonton.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "freelancemw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "friseur-foerder.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fsavc.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fundingrainbows.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -68895,7 +68853,6 @@ { "name": "innvisiondesign.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ionplesalexandru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ipschool.spb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ipsecurelink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ireaco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "israelil-leumi.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "israelil-leumidev.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -69509,7 +69466,6 @@ { "name": "oriontravel.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "outwesthunts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "passau-webdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "paymyphysician.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peers.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "personalnames.net.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pharmacistinfo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -74954,7 +74910,6 @@ { "name": "aviteng.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aviteng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "axault.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "babyboutique.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bachmatt-baar.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bachweid-baar.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bastide-viens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -76759,7 +76714,6 @@ { "name": "inkthreadable.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "inpatec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "intelligentcontacts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "intelligentnegotiator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "introspectivemarketresearch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "investinweed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "invetep.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -80101,7 +80055,6 @@ { "name": "pmcc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "podxappa.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "polybius.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "portalaltadefinicao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "post.icu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "probazen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "programme-phenix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -80842,7 +80795,6 @@ { "name": "wismile.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wolftain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wolvesvtc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "wordadmin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "worldtravelandadventure.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wormate.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xcraftsumulator.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -81291,10 +81243,8 @@ { "name": "siwek.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "skynetstores.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "slymak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "snowrippers.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "soket.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "southmill.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "spd-porta-westfalica.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "spm.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "springboardsandmore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "squareforums.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -81673,7 +81623,6 @@ { "name": "caregiverva.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "carolinaallergyandasthma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "casabella.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "casamarrom.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "catchcrabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ceditedv.com.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cefinco.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -82025,7 +81974,6 @@ { "name": "mon-butin.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "monarchpartnersgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mooveo.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "morritosfelices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "motivational-babes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "motor-agro.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mox.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -82823,7 +82771,6 @@ { "name": "pheros.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pheroz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "phillippe-lemarc.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pikboxstore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pippenainteasy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "piraeuspress.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pjgj18.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -84206,7 +84153,6 @@ { "name": "xyzzyyyz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yearli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yhanthydech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "yulliaschool.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yyffqq.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zeit.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zeit.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -84502,7 +84448,6 @@ { "name": "crcd.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cruelporn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "csodaorszagovoda.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ctrl.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cuacamaungon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cubyhome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cuckmysock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -87133,7 +87078,6 @@ { "name": "zidanpainting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zumtaedanceschool.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zupit.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "zz772.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "120percent-inc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "1244546066.rsc.cdn77.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "2x.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -87702,7 +87646,6 @@ { "name": "just4new.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "k88231.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "k8v05.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "kallisto.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kanzlei-hhh.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kaplanco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kasasaprotect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -87937,7 +87880,6 @@ { "name": "p-art.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "painetcompagnie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "paint4.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pdstudios.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pdtech.ltd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pem-jp.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peter-hennes.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -88809,7 +88751,6 @@ { "name": "jamesrush.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jan-bretschneider.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "janbretschneider.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "japansquared.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jdvargaz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jeffok.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jessecharlie.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -91552,7 +91493,6 @@ { "name": "macramos.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mague.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "maligne-intercites.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "manguyen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "marekkorlak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "marketing91.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "marypatriotnews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -92607,7 +92547,6 @@ { "name": "estumarca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eviadc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "exoticspecialist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "explorecams.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "extrememusclepump.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "f-csc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "faeriebabe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -94899,7 +94838,6 @@ { "name": "country-games.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "country-house.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "countrysidebar.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "coupy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "covid19.melbourne", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "covid19responsepod.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cphollywoodproduct.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -101905,7 +101843,6 @@ { "name": "weblogia.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webmarcosmarquez.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webmetallica.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "webmethod.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webmining.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "weboflies.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webparallax.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -102199,7 +102136,6 @@ { "name": "yoshkar-ola-city.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "youla.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "young-celebrities.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "young-zy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yourbreakfast.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yourdemowebsite.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yourdrive.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -103070,7 +103006,6 @@ { "name": "confirmit.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "connectedbynexus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "covid19resilience.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "cp061.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cpanels.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cpshr.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "crafterbase.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -103369,7 +103304,6 @@ { "name": "rogeriosantos.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rogo.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rpi-pihole-mon.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "rua.ink", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rueckgr.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rundh-audio.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ruttenadvocaat.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -103681,7 +103615,6 @@ { "name": "houseofaceonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "htikeagkyaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ifnet.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ihongchao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "imap.support", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "imqyw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "industriascruzcentro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -105829,7 +105762,6 @@ { "name": "eucustody.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eventticketscenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "everettduiattorneys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ewheelnigeria.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "f-bbs.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "f30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "f3r.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -106538,7 +106470,6 @@ { "name": "iprash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "irwinvalera.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "isinolsun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "islide-powerpoint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iszy.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "iszy.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "itaro.bot", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -106746,7 +106677,6 @@ { "name": "tecnologia.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tecnomagazine.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "teknologiia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tempoprimo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "teplo-russia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "termodej.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tescomobile.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -108977,7 +108907,6 @@ { "name": "dispemec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dnratthee.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "donacarlota.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "draft.cards", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "drivehub.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "drrenointerior.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ecocleanpower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -110539,7 +110468,6 @@ { "name": "axisdesignarchitects.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "babacloud.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "backlinksgenerator.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "badeand.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "badwi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "baocaosuhp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bathrobes.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -111001,7 +110929,6 @@ { "name": "sylino.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "t-dent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tafusu-support.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tappyshop.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "taylored.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tchatland.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tci-style.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -111854,7 +111781,6 @@ { "name": "gimnazijapg.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "globalautomation.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "globalbusinessnews.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "goforcex.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "goldnbraces.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "goodbot.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "grancordobahoy.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112288,8 +112214,6 @@ { "name": "contributopia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "coolink.pub", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "corporateinbound.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "cortadoradeplasma.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "cortapelos.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cosmoswaterdamagerestoration.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "courtsunlimitedut.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "creartcompany.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112408,7 +112332,6 @@ { "name": "framazic.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "framemo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "framinetest.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "fregona.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "frothy285.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gamesbap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "generateur-thot.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112505,7 +112428,6 @@ { "name": "matehierba.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mattisclever.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meaqua.love", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "medidordecampo.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "metalmonocle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "milr.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "minermonitoring.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112515,8 +112437,6 @@ { "name": "moliporex.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "montessori-oberhaching.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mrfd.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mundopatchwork.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mundosai.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mutuocasafacile.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "myofficerenovation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mypaperpress.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112552,7 +112472,6 @@ { "name": "pediatricdentistslilburnga.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pedradatattoosupplies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peelmachineryrepair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "percherosdepared.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "petevagabond.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "peya.tokyo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "photosight.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112566,7 +112485,6 @@ { "name": "politicnation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ponpon05.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "porno-geschichten.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "portaequipajes.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "powderspraymachine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "preconstruct.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "privally.global", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112613,7 +112531,6 @@ { "name": "smart-profile.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sociopampers.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "solocalcetines.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "sonometro.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "souravbhor.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sparanoid.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sqhs.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112654,18 +112571,15 @@ { "name": "tiendatecnologica.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tiktok.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tishsglitches.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "titiansgirl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tmstats.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tontonroger.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "top1.com.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "toplevel.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tornos.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "townofgoldenmeadow-la.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "trouvons.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ttcmed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tubach.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tuckmeintebo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tudorrosesamplerguild.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "turkmen.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "turnbacktogod.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "twidy.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112818,7 +112732,6 @@ { "name": "danieldrozdik.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "daniellecavazos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "darkthreat.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "davangarte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "decorsolucionesgraficas.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dietrichinocencio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "digitalrowdy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112839,7 +112752,6 @@ { "name": "emprendefinanzas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "encrypt.my.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "epilino.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "esterilizador.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ethanyoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ettgottliv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "etudes-litteraires.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -112989,7 +112901,6 @@ { "name": "olamisys.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "olamisys.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "oliveconcept.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ollaexpress.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "open.my.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "osobniterapeutka.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "palem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -113358,7 +113269,6 @@ { "name": "iczer.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "igolf.in.th", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "igorina.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "iguru.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ihsangans.my.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ilovias-farm.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "index.law", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -113531,7 +113441,6 @@ { "name": "revoluruguay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rizikaockovani.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rodoelectrodomesticos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "roenhorst.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "s.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sallah-kw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "saltlakedjcompany.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -113731,7 +113640,6 @@ { "name": "amazcode.ooo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ambrosiamosaicos.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "americolorcorp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ammboi.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "amolador.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "amolare.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "amollare.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -113771,7 +113679,6 @@ { "name": "auguth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "auralinna.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "australianhomemade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "autoaudio.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "autobiz.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "autoone.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "axamansard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -114228,7 +114135,6 @@ { "name": "jackvalley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jagad.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jamesredmond.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "jardineras.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jasminedirectory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jboho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "jdu.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -114354,7 +114260,6 @@ { "name": "mathieugrant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "matti01.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mavidemaravilhas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "maxweber.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mbgalaxy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mbmc.gov.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mcbooks.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -114585,7 +114490,6 @@ { "name": "scai.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sctiger.men", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "seanmeedevworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "searchenginereports.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "secure-cooprincon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "securerepository.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "securityx.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -114857,7 +114761,6 @@ { "name": "anontekno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aprofunda.art.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aquacitylands.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "arbolesdenavidad.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arpasix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arpasix.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arpasix.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -115068,7 +114971,6 @@ { "name": "luparacoes.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "luxegram.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "luxegram.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "manualidadespararegalar.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "manufacturedhomemoving.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "masajeadorespremium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mayflowercreative.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -115120,7 +115022,6 @@ { "name": "omgpu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "opus-nail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "orbik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "osmosis-inversa.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ovenrepairaustin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "paintballer.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "patel.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -115166,7 +115067,6 @@ { "name": "seattlebasementwaterproofers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "securebizneshost.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "secureinfo.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "sembska.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "senork.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sharpyspawn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shuftipro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -115386,7 +115286,6 @@ { "name": "elypia.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "emigrussia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "englishclassworksheets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "enremoto.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "esauth.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eshop-ptz.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eshoprzd.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -115403,7 +115302,6 @@ { "name": "formhub.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "freeassange.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "freelyplaygames.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "fresadora.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fschts.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fujijin.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fydoo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -116138,7 +116036,6 @@ { "name": "totalsell.marketing", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tradition-immobilier.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "trigate.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "troqueladoras.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "truckscout24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "trydoggo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tureceta.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -116435,7 +116332,6 @@ { "name": "mui.kitchen", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "muii.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "muii.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mundoscrapbooking.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "muziekcentrumdebijloke.gent", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "myacroapparel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "myrevolution.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -116759,7 +116655,6 @@ { "name": "gsiw.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "guanggaonet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hackathonjr.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "happywater.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hax.sc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "healthyfoodster.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "healthykitchen33.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -116782,7 +116677,6 @@ { "name": "inmonteblandinio.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "innabilawgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "insidergazette.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "intdemocratic.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "interval-training-timer.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "invantive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "invantive.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -116984,7 +116878,6 @@ { "name": "swissgrid.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "syakeapps.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tahugocilebut.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "tapio.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "taylorfry.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "teast.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ten.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -118107,7 +118000,6 @@ { "name": "meideas108.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mejitravelcr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "melbet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mendmybackprogram.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "merry.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "metait.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "metasearch.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -118698,7 +118590,6 @@ { "name": "houthandelbunskoek.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "houthandeljacobs.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "huemul.studio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "hugobarral.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "huntingtonestateproperties.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hv-online.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hypnotic-reviews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -119531,7 +119422,6 @@ { "name": "puremosquito.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "purepestandlawn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "puresanitization.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "pusatcucikarpet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pxld.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "qualitymark.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "quayhudanhbai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -120196,7 +120086,6 @@ { "name": "osaki.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ostra.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ostracize.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "outdoormanufaktur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "oversimplifiedstatistics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "oxygenserv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pablofonta.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -120293,7 +120182,6 @@ { "name": "regtify.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "regtify.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "regtify.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "reiseziel-hiddensee.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "remontmebliv.lviv.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "remy-daillet-wiedemann.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "repairmysolarpanels.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -120316,7 +120204,6 @@ { "name": "sarayeirani.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sarkaribabu.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "savetomp3.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "savvysme.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "scholarships.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "schubertnest.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sdhb.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -120558,7 +120445,6 @@ { "name": "actris.ac.cy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adala.com.kw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adaptivecenter.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "adelaidecoldlaser.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adgift.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adon.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "adserve.works", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -120576,7 +120462,6 @@ { "name": "agptco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aguidetolovelossanddesperation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ahliqqpoker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ahvassociates.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aidez-moi.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "air-planning.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "aitrading.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -120912,7 +120797,6 @@ { "name": "fotklinikenvarnamo.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fotontechnik.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "frames-eyelash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "francebattery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "francisbaconnet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "franciscadelasllagasvirtual.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fraser-hann.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -121043,7 +120927,6 @@ { "name": "holocron.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "home-ncj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hopefultexas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "horseboxheaven.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "horseconsult.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hostpoint-static.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "houseofannubis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -124872,7 +124755,6 @@ { "name": "pawelurbanski.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pawson.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "paycardtech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "paystarkagency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pcbarchitect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pckartel.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pcmasters.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -126157,7 +126039,6 @@ { "name": "yandong.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yasmingarcia.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "yephy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yhn.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yogaangels.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "yoneda-paint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -126460,7 +126341,6 @@ { "name": "casecandy.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "casualiswebs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "catalogocarrefour.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "catmash.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "centenodigital.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "centreautofronton.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "centurionplumber24-7.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -126809,7 +126689,6 @@ { "name": "goldschmiede-suessenguth.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gomelagromashplus.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "goprozone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "gotleanderpi.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "goto.archi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "goyumoilexpeller.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "graetgossip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -127792,7 +127671,6 @@ { "name": "wiipo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wijkstation.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wikibulz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "wildbox.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "willighp.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "win.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "winmix.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -129385,7 +129263,6 @@ { "name": "sangreytinta.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sanitairkiezer.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "santarosadetail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "satangcorp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sateahafreedi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "satellitetelevision.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sbercontactmonitoring.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -129582,7 +129459,6 @@ { "name": "txtnovel.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ubun.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "udaneprzepisy.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "uls.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "under15.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "undercliff.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "undercucho.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -129991,7 +129867,6 @@ { "name": "holger-schwarze.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "holiy.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hollandhouse.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "horoscopos-amor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hostingsupremo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hrka.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hrka.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -130040,7 +129915,6 @@ { "name": "kimbunlar.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kittybot.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kleemans.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "kodineuerleben.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "komarex.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "komlangs.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "krakenrobotik.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -131495,7 +131369,6 @@ { "name": "appearinsequel.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "appleexterminating.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "appleric.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "appsecmonkey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arbeidsplassen.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "arch-design.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ardacar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -131865,7 +131738,6 @@ { "name": "completecase.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "conjurer.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "constcorrect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "consultiam.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "continuousmonitoringplatform.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cookingwithrakhi.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "copyrightforabout.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -132715,7 +132587,6 @@ { "name": "lorcalive.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "losedata.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "losmejoressmartwatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lovehoneystore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "luc.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lucascosta-ido.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lucasmateus.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -133697,7 +133568,6 @@ { "name": "themegatones.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "themizellbrothers.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "theocratic.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "theologique.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "thepilotwoman.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "thepilotwoman.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "thepinecones.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -134509,7 +134379,6 @@ { "name": "flyserver.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "followthepin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "folwark.krakow.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "football.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "foropl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "forsat.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "franchisechaodoi-cambodia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -134828,7 +134697,6 @@ { "name": "meinvergleich.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mejor-broker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "menno.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "meow.enterprises", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "merklin.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meticore.promo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mezzomusicschool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -135236,7 +135104,6 @@ { "name": "werk32.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "werkenbijbuvo.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wettbuero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "wette.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "whangareimusic.org.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "whittle.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "whizz.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -135286,6 +135153,1262 @@ { "name": "zkoclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zlr.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zonesons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "0b1.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "195theglobe.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1brd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1xde.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3n5b.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "51acg.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "7eastgenetics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "80daysofsummer.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "900hosting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "900pk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "95-the-mix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "9vdy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "a699.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abonemnet.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abri29.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acaciawellbeing.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acadianteas.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acarotheca.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "accesseap.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "achatroom.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acnoventa.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "addiesel.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adjustingoursails.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adminportal-dev.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adrieng.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "advancedhealthmedical.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agamabox.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aimsoftnet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aircompressormachine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "airmanproduction.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ak-vsk.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ale5000.altervista.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allthefallen.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amansinghbhogal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ameba-capital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amelierose.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "americancasinoguide.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amerikasepetim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amped4ski.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "andonivr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "andreas-kurtz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "andrew-lazarev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "angiology.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anikabyaabi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "antennekaart.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "antivigilancia.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aorangi-debt.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "appoggiature.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "appopay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aquatechnic.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arabianlingo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arbolesdenavidad.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "archeologiegorinchem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arkadiumdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "armamentevolved.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artmaterials.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artwhale.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asianmaterials.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "askindia.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aspirateur-univers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asro.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "assistancepaws.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "atriballi.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aurelie-valognes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "automodulegods.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "auturoa.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avai.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avakore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avtours.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "awood.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "axel-faure.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "backingtrackbrasil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baidutrustssl.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baidutrustssl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "banshkhalitimes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baraklava.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barleyandbirch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barnabasgolf.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baroccofashion.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barrahome.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "basedriver.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bbppkdanpkk.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bcrypt.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beager.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bearzoutdoor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bekoplc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bels-lijntje.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawabundant.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawafter.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawamazing.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawanchor.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawarrow.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawatlantic.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawavatar.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbattle.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawblaster.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawblod.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbody.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbounce.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbrite.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbrowse.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbrowser.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbuddies.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbuller.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawbunny.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcache.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcalculator.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcamel.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcaptive.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcarnival.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcatch.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcatcher.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcellar.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcharm.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcharte.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcharts.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcheaper.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawconstruct.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcorporation.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcounty.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcreativity.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcrunch.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcrystal.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawctktom.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcupid.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawcuriotk.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawdepot.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawdesigning.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawdestination.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawdivine.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawdodge.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawdollars.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawdowntown.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawduck.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlaweagle.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawebony.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawecho.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawecono.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawelectra.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawenvy.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawepic.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawfalcon.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawfame.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawfighter.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawflavor.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawfolder.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgang.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgecko.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgeo.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawglamour.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawglory.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgoddess.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgorilla.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgrab.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgrabber.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgrace.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgram.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgratis.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgroove.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgrow.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawguerilla.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawguerrilla.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawgun.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawhands.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawhandsome.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawhandy.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawhard.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawhotrod.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawhtkky.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawice.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawimagine.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawintergrity.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawiron.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawjackpot.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawjewel.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawjoker.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawjtkt.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawkayak.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawkiss.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawknight.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlast.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlastminute.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlegacy.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawless.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlightning.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlimited.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlion.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlittle.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawloco.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlowprice.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawlucky.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmain.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmarks.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmatche.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmeasure.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmember.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmessenger.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmeta.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmetric.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmillions.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawminer.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmtkcle.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawmystical.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnano.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnational.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnations.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnatural.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnight.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnobel.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnormal.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnorthamerican.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawnumber.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawocity.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawoffline.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawoftheday.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawomatic.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawomega.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawoneday.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawopedia.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawopplis.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlaworama.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlaworiginal.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawother.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawouter.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlawover.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beyondthecrater.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bezbankrotstva.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bigsaleclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bilalozdemir.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bilibili.party", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "binair-e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bintra.directory", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bio-verzeichnis.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bionne.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "birdersunite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blackbettybbq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blockchainaiintegra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bloomingpink.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blossom.so", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bluffelectrician.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "booktook.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bougeer.gent", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "braveagency.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brilhante.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brunobeauvoir.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brweb.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buffalojewishfederation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessadaptive.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessafter.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessarrow.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessbad.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessbody.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessbrite.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessbrowse.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessbuller.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessbunny.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscaster.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscharm.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscharts.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscircus.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscollect.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscollections.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscolor.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscommission.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscupcake.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscupid.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesscurious.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessdelta.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessdodge.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessdollar.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessdollars.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessdragon.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessduck.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesseastside.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessecho.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessepic.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessexcel.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessfame.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessfeature.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessfeedback.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessfiesta.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessfighter.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessfleet.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessflower.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessgang.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessgrace.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessgun.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesshandsome.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessincolumbus.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessindetroit.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessinelpaso.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessinfortworth.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessinhouston.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessinindianapolis.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessinnashville.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessinnashville.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessinsanantonio.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessinwashington.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesskayak.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesskiss.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessknight.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessless.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesslion.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessloco.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesslowprice.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessmarks.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessmetric.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessnatural.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessnight.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessoftheday.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessomatic.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessopedia.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessother.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessouter.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesspart.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesspassport.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesspeace.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesspearl.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessphase.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesspicker.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesspipe.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesspremium.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesspure.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessreps.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessrequest.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessrex.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessrhino.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessroll.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessrunners.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessscapes.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesssend.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessshoot.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessslide.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesssouthbeach.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesssparkle.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesssplash.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessstamp.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesssurreal.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessthunder.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessunder.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessuprise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessvisual.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businesswaterfront.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "businessworth.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buzzsmithmusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "by.place", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "caj-eichstaett.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "californiabudgetfinance.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camped.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cangku.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "capeprivacy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "capris.cr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cargomurah.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cartegrise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "casinocity.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "castillo.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "catland.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cbddo.gov.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "certidao-nascimento-pt.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chamberlinfoundation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "changetowellness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chat-buddy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chattomania.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chefforaday.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cherbourg.website", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chosting.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chur-arosa-bahn.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chur-arosa-bahn.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "circuits-courts.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ckcameron.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clementluck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coconutscrapbooking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "complete-concrete-concise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "compradalweb.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "conciergeofcare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "congresodermatologia2019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "connyduck.art", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "connyduck.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coolansplanet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "corebit.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cortadorplasma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "counterespionage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "countryatheartcandles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crealab.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "credentsys.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creditoconsolidado.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creepnt.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cronmaster.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cuboatomico.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "culinoa.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "curiosoando.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cursoderecepcionistadehotel.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyber-resear.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyberelements.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dachdeckermeister-moeller.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dapurocha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datacentresupport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datapathology.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datdt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "davichete.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dchublist.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "debianizzati.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deephouse.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dehnermd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "der-elite.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "designpro.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diademuertos.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dianadeluxe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "digitaldragonsinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diipoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ding.gent", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diospersonal.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "direitonovo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "distract09.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dl444.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dnk.global", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dnssex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "do-it-service.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dobrynyastyle.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doeprojects.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dom-rz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dominionpowerassembly.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doudo.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "douvan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dpsmassage.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dragonboat.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "draussen.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drobina.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drvondawright.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dutton.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dylancl.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e-pns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e-skalniak.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e34club.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eandata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "earthsong.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eaton-daitron.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eax.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ebatech-energiemanagement.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "edibleimagesupplies.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "educationplannerbc.ac", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "egzotique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elblogdezoe.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elevated-esthetics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elmejorcortapelos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elnababy.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emlaknabzi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emls.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emmadreams.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "empreendedorsmart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enbarra.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "energyconsultonline.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "entrepreneurnight.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "epiclawnpro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "essex.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiarauxiliardefarmacia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiarcoachingdeportivo.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiarcocinaonline.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiarenergiasrenovablesonline.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiaresteticaonline.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiarnaturopatia.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiarseguridadprivada.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "european-village.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "everydaydishes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "everymanandhisdogvineyard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evilcodes.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fabulouseventsmiami.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "facialflex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fallenlondon.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "famigliafiorini.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "faqbite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "faribanx-xxx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fdi-service.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fertilityspace.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feuerwehr-e-learning.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fibery.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "filmwatch.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fionna.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fixedmatch.bet", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fjordtorsk.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flourishdx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodafter.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodagenda.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodarrow.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodatlantic.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodauthority.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodavatar.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodbeast.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodblod.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodbrowse.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodbuller.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodcamel.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodcheapest.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodclearance.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodcorporation.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodcrafter.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodcreativity.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fooddivine.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fooddodge.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fooddollars.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodeastbay.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodescrow.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodexcel.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodgoddess.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodgratis.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodguerrilla.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodhotrod.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodhusky.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodjoker.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodkayak.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodlightning.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodlimited.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodnations.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodomega.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodpearl.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodpermanent.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodplatinum.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "forumdimo.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freetamco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freinetmiddenschool.gent", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fresadorasytornos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "from.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fsscms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fssp-bordeaux.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "furuy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "g-printec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gabijazava.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "galaperfume.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gamebillingcentre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gameqoin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gamingdirectory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gatoslivres.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gefire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gehirnstatus.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gempool.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gentholidayland.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gentholidayland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "genuineppe.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "georgiacriminaldefense.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "geosno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gera-haushaltsaufloesung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "getahearing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "glenmarieproperties.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gmc-mca.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gogo.mn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "golden-jackass.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "goldensunmfg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "golfkulur.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "golyatsec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "goodfundsgateway.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "goodwincasinos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gopronto.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gorunningtours.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gottasketchemall.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grafmark.art", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grandmasternetwork.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "greatwebventure.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "greenrose.od.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gridcatalyst.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grimdarkterrain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gura.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haberlandconsulting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haberlanddesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haberlanddigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haberlandgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haberlandoutreach.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haberlandpartners.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haberlandpodcasts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haberlandtalents.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "halfbeastest.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hanspetersteiger.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "happydyes.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haus.bio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hausfrauficken.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hawaiiherb.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hawo.academy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hbo-center.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthabundant.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healtharrow.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthatlantic.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthatlantic.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthbeltsville.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthbinghamton.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthbolton.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthbordelonville.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthboulevard.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthbounce.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthbrisbane.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthchillicothe.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthclyman.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthconfluence.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthculloden.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthemden.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthfrederick.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthfreeport.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthgrandrapids.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthharrisburg.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthhelena.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthhendersonville.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthhuntsville.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthjarrettsville.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthlincoln.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthlongwood.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthmiami.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthmountolive.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthnorman.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthnorthgreenbush.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthoakbrook.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthoakland.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthpaducah.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthrangely.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthreno.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthrivergrove.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthsanluisobispo.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthsantaana.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthsomerset.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthsouthfield.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthtacoma.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthveedersburg.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthwausau.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthwichita.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthysteps.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hearingclinicgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heckhome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heliobil.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "helochic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hemagon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hidelinkz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hinketsujyoshi-no-torisetsu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hofpleinlijn.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hogyerzedmagad.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homecache.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homecaster.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homecatch.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homecharte.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homechase.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeclient.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homecollections.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homecrawler.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignakron.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignarvada.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignboston.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignbuffalo.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigncary.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignclinton.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignclovis.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigncolorado.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigncorona.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigndayton.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigndowney.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignedison.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigneugene.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignfontana.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignfrisco.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigngarland.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigngilbert.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignhartford.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignhayward.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignirvine.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignmacon.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignmiami.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignnewyork.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignoakland.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignomaha.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignontario.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignorlando.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignoxnard.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignpaterson.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignpeoria.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignplano.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignportland.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignraleigh.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignrichmond.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignsandiego.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignsanfrancisco.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignsantaana.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignseattle.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignstamford.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigntampa.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigntoledo.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigntucson.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesigntulsa.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignventura.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedesignwashington.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homedollars.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeeagle.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeflag.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeformula.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homegang.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homegeo.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homegun.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeindiainfratech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeinteriorasia.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homekiss.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeletter.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homelion.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homemarks.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homemember.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homemessenger.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homenight.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homenumber.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeopplis.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeorama.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeover.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homepassport.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homepatch.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homepropertynews.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homerail.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homerequest.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homerex.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homesonic.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homestamp.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homestick.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homestreaming.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeunder.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homevisual.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homewidget.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homewinner.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homewish.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hooqshot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hotbabesplus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hotel-villaelaia.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "humanrights.gov.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hutchh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hyza.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "i-li.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "icaleo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "icon-art.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ieeeaast.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "igamingdirectory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "igamingsuppliers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ijmondlijn.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ikra24.in.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ilife.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ilonpolku.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ilsc.ngo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "indexpert.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "indianapolispsychologistsest.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "indiesports.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infobarunih.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inova.business", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "intercomunicadores.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inzidenz.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ip-audio.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ipwho.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iroisedh.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "irturkey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "is256.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "isabellainlove.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "isantv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iseecure.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "island-line.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "island-line.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "itousweb.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ivan770.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "izkustvo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jansendermatografie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jasonchampagne.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jbootsma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jcsobrasyreformas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jeng.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jetstreampro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jewishphilanthropies.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jgraca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jjhof.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jjsguitarpickups.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jmtk.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jnx.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "joeshare.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "joeshimkus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jogoshoje.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "joiceorthopaedics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "joycosmetics.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "juegosalcubo.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "julene.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "julianaferrari.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "juzgadocaldas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaha.co.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kanz.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "karppaamo.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kelcible.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kendev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kerrynbutlergardens.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "khounegi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kingston-fear.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kleinhapl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "klexhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "klinikatlantis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "klothsfrance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kolabtree.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kommerciya.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kompliant.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "korporativnabezbednost.rs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kreolis.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kukiulpindo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kuon.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kyrabanx.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ladyanja.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lagoscooperativecollege.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lakestclairguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lam.ngo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lasersafety.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laszloinstitute.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lauxlawyers.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lavishhobbies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leakfix.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "learn2fly.training", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leastern.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lecciculturadelvino.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leebladon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lesnoticiesdensergialarcon.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lexdavicont.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lialeone.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "libbysbooks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "liehuojun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "limestart.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "linamila.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lindner-edv.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lingshan.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lisslonglegs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "livecast.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "livedomain.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lmsowl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loli.com.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loli.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loliloli.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lolnews.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lophtalmo.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lossandthemourningafter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "louyu.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lskl.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lucrebem.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ludovicfernez.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lustrecloud.art", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "luyungterd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "macarthuradr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "magenkompass.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "magnum-sadoshima.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mahieu-wonen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maitrelucas.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "malagarental.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "malareal.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "malaysiatxt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "malkalni.lv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marketsosyali.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marlboroughchamber.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marshmallowchallenge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "martex.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marykirsch.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "masterenciberseguridadonline.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "masterenenologiaonline.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "masterenmarketingdigitaldq.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "masteringenieriadelfuego.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matts.software", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maxh.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mbwsignup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medscope.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mejorfiltrodeagua.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "melbournehousesitters.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meli-deluxe.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mendelsphotography.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "miekesandersuitvaart.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "milano-web.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "minamassimo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mircreditov.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mixedbagashley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkdevice.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkey-solution.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkey-solutions.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkey-solutions.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkeysolution.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkeysolutions.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkeysolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mkvhds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mlpavimentosdehormigonimpreso.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "modderday.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "modernqr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mohelafederal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mondayaftersunday.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "montre-luxe-occasion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "montyvlogs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "motiondata-vector.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "motiondreamatix.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "msoc.gent", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mtehe-square.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "multivpn.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mungdog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mur-parfait.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mwpromotion.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "my-store.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myfasttrack-uat.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mysecurity.review", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mywpdesign.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mywpdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nadadigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "namevirus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nara.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nataliealba.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nature-avenue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "natures-design.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "negociosnow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netticasinosivut.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "neurolicht.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newapparatus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newportbus.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nicholshydroseeding.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nicokroon.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "niedermair.bz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "night-academy.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nimbus-link.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nimbuslink.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nittel-gaertner.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "northstarcybersecurity.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "northteksystems.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "notari.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noyoga.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ns230kvopenhouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nugratis.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nuvoagency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "odo.dyn.home-webserver.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "officedivvy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "officedivvy.company", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "offshorewindwatchdog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ohs.on.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oliviers-co.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onlinecasinoreviewz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onlyfitgear.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "operacionlimpieza.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opticsschool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "optionsloop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ostrausercontent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ovejaninja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "owo.enterprises", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pablo-serrano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pagalworld.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pagalworld.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pagalworld.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pagalworld.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "palladiumtechs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "palmcoastbusinessnetwork.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pawealthmanagement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pay.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pay.sb", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "payat.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pebblenest.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "penguinvillage.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "percherosdepared.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "perrarus.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "perthvintagelimousines.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petbrowser.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petcharte.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petclassy.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petclient.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petcolor.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petra-toroid.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pewglobal.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "philipasmundson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "philipthomas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pilotandy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pinterest.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pirzl.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pixeltranslating.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pocketgamingdirectory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pokerzone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "polsonlawfirm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pooltest.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "popcarte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "portiapp.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "premium-shop.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "privacycentermqt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pro-box.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "professionalportfolio.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "projectmanager.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "projectzethes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prosperityprojectaz.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "proxybay.how", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pti-property.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "puzzleswaps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qitzune.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rabbitcare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "railsimulator.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ramonadeluxe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ranker.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rc2edit.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reaff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "realgiulianova.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rebill.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "redefineyounow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "redstoneinvest.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "refillrx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "relocatetocornwall.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reparacionmovilescartagena.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "robinsoncontracting.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "romanovamakeup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "royal73.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rpo97.fm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rsreinvest.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rssalvino.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "runwaybpo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rusmir.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rutasindonesia.viajes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "s-w-o-p.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sailboatdata.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sakiyamagumi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "salon-stil-leben.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "samclarke.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "samscollection.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sanalsergi.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "santafesilversaddlemotel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saudecoluna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "save-me-aachen.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "savesilvercreek.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "savesomegreen.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scaffoldingsandton.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "schatderer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scholar.pk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "schumacher-at-home.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "schworak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scloud.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scommessenonaams.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scootermalagarental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scor.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scrawn.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "secureqbplugin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seitanic-cookbook.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seokaos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sexyleni.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shigizemi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shiplapandshells.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shlink.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shnuff.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoilpeek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingavatar.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingboulevard.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingbrite.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingcatch.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingsunflower.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingsuperhero.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingthunder.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingtreasure.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingtreats.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingturbo.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingunique.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingvariety.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingwinner.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingworth.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shota.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shuhra.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sidneyhaberland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simsfinnchiropractic.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sirenasweet.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sitesara.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sitiocasabranca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sivutoimisto.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skinnybitch99.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skipbinsforhire.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smashbylaney.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soccerbetwinner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sochiatrium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "socseti.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sold.red", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soloproductos.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soniclaunchpad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soundslike.gent", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "southtoowoombahawks.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spa-et-sauna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sparklyfairy.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sparrowwallet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spbot.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "specialfeetforce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "speedvitals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spellchecksquatting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spendesk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spina-help.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sporto24.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sportwette.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ssantosserralharia.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "standardstraversal.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "starprime.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "starprime.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "starwarschronology.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "steelportknife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "steffko.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "steinmassl.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stellar.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stift-kremsmuenster.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stories-event.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stovokzal.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "strawpoll.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stroitelstvopro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "studentinaneta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "studiweb.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stunningautos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sugarfetch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "supergrandmasternetwork.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "superiorseamlessinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "supermedia.cool", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suplindex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suwebcreativa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swiftmod.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swiftmodcdn.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swvc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tabsi.edu.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tad.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tagasi.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "talcualdigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "talentis.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tannlegenityrkia.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tarimaferial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tartufomajella.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tatahealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teamb.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teamtotal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "techno-blog.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "technologycaptive.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "technologycellar.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "technologyclassy.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "technologycollections.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "technologycollector.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "temydee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tentagent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "texogroup.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thebrewroom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thecowboy.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theemeraldmagazine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thefoxstrousers.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thefuturetech.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thejunctionstudios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thekassa.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thepodcastreviewshow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thesilentlink.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thewindowsclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thoreauskalendar.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "threeriversopenhouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thrivinggracefully.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ticketunity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tiendamaspatchwork.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "timeslive.co.ke", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "timeticket.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "timeticket.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "to4ka.md", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "toby.party", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "todaynewsafrica.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "todosquerem.uno", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tokiomarine.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "toldosecoberturasbh.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tonebuildingsupplies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tonimorena.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "topppinfo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelpearl.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelpremier.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelpride.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelrates.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelsignature.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelsurprise.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelthunder.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelturbo.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelultra.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelvictory.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trendegypt.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trhknih.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trimyourbushforallah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "troisiemeoeil.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trycultivate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tuasaudehoje.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tudinhoparasuacasa.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tudosobrevidaesaude.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "turkcoder.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "turksell.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tweedandtalon.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "twinspringcoupling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "twobrothersbbq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "type74.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "u15.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "u15x.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ubc.ac", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uchuumontreal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ufanet.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uk-cbdoils.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unap.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "underdogstres.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unian.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unine.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "urbanfoodmarket.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "usatodaynetworkservice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vaitcampus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "veber.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vega.education", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "veniajuridico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "verafin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "verimoto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vertiko.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "viega.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "viega.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "viega.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visegradtours.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "volt.od.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "voluntarist.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vondenstein.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "votrepolice.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wahay.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "waifu.gallery", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wearewp.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webblawmaine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webcasinos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webcazip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webcreaciones.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weifengqi18.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wespringforward.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wessco.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westcoastlabels.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westskinlaser.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westvilleplumber.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westwingopenhouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wettbonus.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wfq2020.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "whisperlab.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wildbirdsuets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "winnlandscaping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "withprocess.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wmakemarketing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "woltlab-demo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "worldcdg.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wwww.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xashayar.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xchimera.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--90acibo4aazm.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xploredundee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xs4ever.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xxxomas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yawe.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yeecord.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yellow.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yellowmessenger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yengec.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yl-invest.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yogiekw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yoomza.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youiv100.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youiv3.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youiv4.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youiv4k.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youiv5.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youiv6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yukino.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zaanlijn.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zdnba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zebraonegallery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zero-0.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zerobelow.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zerobelow.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zerogeworkshop.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zoom-eco.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zootsys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zsi.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, // END OF 1-YEAR BULK HSTS ENTRIES // Only eTLD+1 domains can be submitted automatically to hstspreload.org,
diff --git a/net/log/net_log_values.h b/net/log/net_log_values.h index d7e5401..6e1a362 100644 --- a/net/log/net_log_values.h +++ b/net/log/net_log_values.h
@@ -5,6 +5,7 @@ #ifndef NET_LOG_NET_LOG_VALUES_H_ #define NET_LOG_NET_LOG_VALUES_H_ +#include <stddef.h> #include <stdint.h> #include "base/strings/string_piece_forward.h"
diff --git a/pdf/BUILD.gn b/pdf/BUILD.gn index 289e938d0..a1dc81a 100644 --- a/pdf/BUILD.gn +++ b/pdf/BUILD.gn
@@ -80,6 +80,7 @@ "accessibility.cc", "accessibility.h", "chunk_stream.h", + "content_restriction.h", "document_attachment_info.cc", "document_attachment_info.h", "document_layout.cc",
diff --git a/pdf/content_restriction.h b/pdf/content_restriction.h new file mode 100644 index 0000000..f42be8cb --- /dev/null +++ b/pdf/content_restriction.h
@@ -0,0 +1,26 @@ +// 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 PDF_CONTENT_RESTRICTION_H_ +#define PDF_CONTENT_RESTRICTION_H_ + +namespace chrome_pdf { + +// Used for disabling browser commands because of restrictions on how the data +// is to be used (i.e. can't copy/print). +// TODO(crbug.com/702993): Must be kept in sync with `ContentRestriction` in +// chrome/common/content_restriction.h. While there's a transitive static +// assertion that the enums match, a direct static assertion should be added +// when `PP_ContentRestriction` is removed. +enum ContentRestriction { + kContentRestrictionCopy = 1 << 0, + kContentRestrictionCut = 1 << 1, + kContentRestrictionPaste = 1 << 2, + kContentRestrictionPrint = 1 << 3, + kContentRestrictionSave = 1 << 4 +}; + +} // namespace chrome_pdf + +#endif // PDF_CONTENT_RESTRICTION_H_
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index 53909a3..55e992a 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -29,6 +29,7 @@ #include "net/base/escape.h" #include "pdf/accessibility.h" #include "pdf/accessibility_structs.h" +#include "pdf/content_restriction.h" #include "pdf/document_attachment_info.h" #include "pdf/document_metadata.h" #include "pdf/pdfium/pdfium_engine.h" @@ -999,16 +1000,12 @@ std::unique_ptr<UrlLoader> OutOfProcessInstance::CreateUrlLoader() { if (full_frame()) { - if (!did_call_start_loading_) { - did_call_start_loading_ = true; - pp::PDF::DidStartLoading(this); - } + DidStartLoading(); // Disable save and print until the document is fully loaded, since they // would generate an incomplete document. Need to do this each time we // call DidStartLoading since that resets the content restrictions. - pp::PDF::SetContentRestriction( - this, PP_CONTENT_RESTRICTION_SAVE | PP_CONTENT_RESTRICTION_PRINT); + SetContentRestrictions(kContentRestrictionSave | kContentRestrictionPrint); } return CreateUrlLoaderInternal(); @@ -1036,57 +1033,6 @@ return results; } -void OutOfProcessInstance::DocumentLoadComplete() { - // Clear focus state for OSK. - FormTextFieldFocusChange(false); - - DCHECK_EQ(DocumentLoadState::kLoading, document_load_state()); - set_document_load_state(DocumentLoadState::kComplete); - UserMetricsRecordAction("PDF.LoadSuccess"); - RecordDocumentMetrics(); - - // Note: If we are in print preview mode the scroll location is retained - // across document loads so we don't want to scroll again and override it. - if (IsPrintPreview()) { - if (IsPreviewingPDF(print_preview_page_count_)) { - SendPrintPreviewLoadedNotification(); - } else { - DCHECK_EQ(0, print_preview_loaded_page_count_); - print_preview_loaded_page_count_ = 1; - AppendBlankPrintPreviewPages(); - } - OnGeometryChanged(0, 0); - } - - SendAttachments(); - SendBookmarks(); - SendMetadata(); - SendLoadingProgress(/*percentage=*/100); - - if (accessibility_state() == AccessibilityState::kPending) - LoadAccessibility(); - - if (!full_frame()) - return; - - if (did_call_start_loading_) { - pp::PDF::DidStopLoading(this); - did_call_start_loading_ = false; - } - - int content_restrictions = - PP_CONTENT_RESTRICTION_CUT | PP_CONTENT_RESTRICTION_PASTE; - if (!engine()->HasPermission(PDFEngine::PERMISSION_COPY)) - content_restrictions |= PP_CONTENT_RESTRICTION_COPY; - - if (!engine()->HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY) && - !engine()->HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY)) { - content_restrictions |= PP_CONTENT_RESTRICTION_PRINT; - } - - pp::PDF::SetContentRestriction(this, content_restrictions); -} - void OutOfProcessInstance::RotateClockwise() { engine()->RotateClockwise(); } @@ -1246,10 +1192,7 @@ DCHECK_EQ(DocumentLoadState::kLoading, document_load_state()); UserMetricsRecordAction("PDF.LoadFailure"); - if (did_call_start_loading_) { - pp::PDF::DidStopLoading(this); - did_call_start_loading_ = false; - } + DidStopLoading(); set_document_load_state(DocumentLoadState::kFailed); paint_manager().InvalidateRect(gfx::Rect(plugin_size())); @@ -1461,6 +1404,39 @@ } } +void OutOfProcessInstance::DidStartLoading() { + if (did_call_start_loading_) + return; + + pp::PDF::DidStartLoading(this); + did_call_start_loading_ = true; +} + +void OutOfProcessInstance::DidStopLoading() { + if (!did_call_start_loading_) + return; + + pp::PDF::DidStopLoading(this); + did_call_start_loading_ = false; +} + +void OutOfProcessInstance::OnPrintPreviewLoaded() { + // Scroll location is retained across document loads in print preview mode, so + // there's no need to override the scroll position by scrolling again. + if (IsPreviewingPDF(print_preview_page_count_)) { + SendPrintPreviewLoadedNotification(); + } else { + DCHECK_EQ(0, print_preview_loaded_page_count_); + print_preview_loaded_page_count_ = 1; + AppendBlankPrintPreviewPages(); + } + OnGeometryChanged(0, 0); +} + +void OutOfProcessInstance::SetContentRestrictions(int content_restrictions) { + pp::PDF::SetContentRestriction(this, content_restrictions); +} + void OutOfProcessInstance::UserMetricsRecordAction(const std::string& action) { // TODO(raymes): Move this function to PPB_UMA_Private. pp::PDF::UserMetricsRecordAction(this, pp::Var(action));
diff --git a/pdf/out_of_process_instance.h b/pdf/out_of_process_instance.h index 05afdbcf..ca935356 100644 --- a/pdf/out_of_process_instance.h +++ b/pdf/out_of_process_instance.h
@@ -112,7 +112,6 @@ std::vector<SearchStringResult> SearchString(const char16_t* string, const char16_t* term, bool case_sensitive) override; - void DocumentLoadComplete() override; void DocumentLoadFailed() override; pp::Instance* GetPluginInstance() override; void DocumentHasUnsupportedFeature(const std::string& feature) override; @@ -156,6 +155,10 @@ AccessibilityPageObjects page_objects) override; void SetAccessibilityViewportInfo( const AccessibilityViewportInfo& viewport_info) override; + void SetContentRestrictions(int content_restrictions) override; + void DidStartLoading() override; + void DidStopLoading() override; + void OnPrintPreviewLoaded() override; void UserMetricsRecordAction(const std::string& action) override; private:
diff --git a/pdf/pdf_view_plugin_base.cc b/pdf/pdf_view_plugin_base.cc index 5e40bae..482d5da 100644 --- a/pdf/pdf_view_plugin_base.cc +++ b/pdf/pdf_view_plugin_base.cc
@@ -34,6 +34,7 @@ #include "net/base/escape.h" #include "pdf/accessibility.h" #include "pdf/accessibility_structs.h" +#include "pdf/content_restriction.h" #include "pdf/document_layout.h" #include "pdf/document_metadata.h" #include "pdf/paint_ready_rect.h" @@ -243,6 +244,44 @@ SendMessage(std::move(message)); } +void PdfViewPluginBase::DocumentLoadComplete() { + DCHECK_EQ(DocumentLoadState::kLoading, document_load_state_); + document_load_state_ = DocumentLoadState::kComplete; + + UserMetricsRecordAction("PDF.LoadSuccess"); + RecordDocumentMetrics(); + + // Clear the focus state for on-screen keyboards. + FormTextFieldFocusChange(false); + + if (IsPrintPreview()) + OnPrintPreviewLoaded(); + + SendAttachments(); + SendBookmarks(); + SendMetadata(); + SendLoadingProgress(/*percentage=*/100); + + if (accessibility_state_ == AccessibilityState::kPending) + LoadAccessibility(); + + if (!full_frame_) + return; + + DidStopLoading(); + + int content_restrictions = kContentRestrictionCut | kContentRestrictionPaste; + if (!engine()->HasPermission(PDFEngine::PERMISSION_COPY)) + content_restrictions |= kContentRestrictionCopy; + + if (!engine()->HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY) && + !engine()->HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY)) { + content_restrictions |= kContentRestrictionPrint; + } + + SetContentRestrictions(content_restrictions); +} + void PdfViewPluginBase::DocumentLoadProgress(uint32_t available, uint32_t doc_size) { double progress = 0.0; @@ -373,97 +412,6 @@ SendMessage(std::move(message)); } -void PdfViewPluginBase::SendAttachments() { - const std::vector<DocumentAttachmentInfo>& attachment_infos = - engine()->GetDocumentAttachmentInfoList(); - if (attachment_infos.empty()) - return; - - base::Value attachments(base::Value::Type::LIST); - for (const DocumentAttachmentInfo& attachment_info : attachment_infos) { - // Send `size` as -1 to indicate that the attachment is too large to be - // downloaded. - const int size = attachment_info.size_bytes <= kMaximumSavedFileSize - ? static_cast<int>(attachment_info.size_bytes) - : -1; - - base::Value attachment(base::Value::Type::DICTIONARY); - attachment.SetStringKey("name", attachment_info.name); - attachment.SetIntKey("size", size); - attachment.SetBoolKey("readable", attachment_info.is_readable); - attachments.Append(std::move(attachment)); - } - - base::Value message(base::Value::Type::DICTIONARY); - message.SetStringKey("type", "attachments"); - message.SetKey("attachmentsData", std::move(attachments)); - SendMessage(std::move(message)); -} - -void PdfViewPluginBase::SendBookmarks() { - base::Value bookmarks = engine()->GetBookmarks(); - if (bookmarks.GetList().empty()) - return; - - base::Value message(base::Value::Type::DICTIONARY); - message.SetStringKey("type", "bookmarks"); - message.SetKey("bookmarksData", std::move(bookmarks)); - SendMessage(std::move(message)); -} - -void PdfViewPluginBase::SendMetadata() { - base::Value metadata(base::Value::Type::DICTIONARY); - const DocumentMetadata& document_metadata = engine()->GetDocumentMetadata(); - - const std::string version = FormatPdfVersion(document_metadata.version); - if (!version.empty()) - metadata.SetStringKey("version", version); - - metadata.SetStringKey("fileSize", - ui::FormatBytes(document_metadata.size_bytes)); - - metadata.SetBoolKey("linearized", document_metadata.linearized); - - if (!document_metadata.title.empty()) - metadata.SetStringKey("title", document_metadata.title); - - if (!document_metadata.author.empty()) - metadata.SetStringKey("author", document_metadata.author); - - if (!document_metadata.subject.empty()) - metadata.SetStringKey("subject", document_metadata.subject); - - if (!document_metadata.keywords.empty()) - metadata.SetStringKey("keywords", document_metadata.keywords); - - if (!document_metadata.creator.empty()) - metadata.SetStringKey("creator", document_metadata.creator); - - if (!document_metadata.producer.empty()) - metadata.SetStringKey("producer", document_metadata.producer); - - if (!document_metadata.creation_date.is_null()) { - metadata.SetStringKey("creationDate", base::TimeFormatShortDateAndTime( - document_metadata.creation_date)); - } - - if (!document_metadata.mod_date.is_null()) { - metadata.SetStringKey("modDate", base::TimeFormatShortDateAndTime( - document_metadata.mod_date)); - } - - metadata.SetStringKey("pageSize", - FormatPageSize(engine()->GetUniformPageSizePoints())); - - metadata.SetBoolKey("canSerializeDocument", - IsSaveDataSizeValid(engine()->GetLoadedByteSize())); - - base::Value message(base::Value::Type::DICTIONARY); - message.SetStringKey("type", "metadata"); - message.SetKey("metadataData", std::move(metadata)); - SendMessage(std::move(message)); -} - void PdfViewPluginBase::SendLoadingProgress(double percentage) { DCHECK(percentage == -1 || (percentage >= 0 && percentage <= 100)); @@ -671,36 +619,6 @@ std::ceil(document_size_.height() * zoom() * device_scale())); } -void PdfViewPluginBase::LoadAccessibility() { - accessibility_state_ = AccessibilityState::kLoaded; - AccessibilityDocInfo doc_info; - doc_info.page_count = engine_->GetNumberOfPages(); - doc_info.text_accessible = - engine_->HasPermission(PDFEngine::PERMISSION_COPY_ACCESSIBLE); - doc_info.text_copyable = engine_->HasPermission(PDFEngine::PERMISSION_COPY); - - // A new document layout will trigger the creation of a new accessibility - // tree, so |next_accessibility_page_index_| should be reset to ignore - // outdated asynchronous calls of PrepareAndSetAccessibilityPageInfo(). - next_accessibility_page_index_ = 0; - SetAccessibilityDocInfo(doc_info); - - // If the document contents isn't accessible, don't send anything more. - if (!(engine_->HasPermission(PDFEngine::PERMISSION_COPY) || - engine_->HasPermission(PDFEngine::PERMISSION_COPY_ACCESSIBLE))) { - return; - } - - PrepareAndSetAccessibilityViewportInfo(); - - // Schedule loading the first page. - ScheduleTaskOnMainThread( - kAccessibilityPageDelay, - base::BindOnce(&PdfViewPluginBase::PrepareAndSetAccessibilityPageInfo, - GetWeakPtr()), - 0); -} - void PdfViewPluginBase::PrepareAndSetAccessibilityPageInfo(int32_t page_index) { // Outdated calls are ignored. if (page_index != next_accessibility_page_index_) @@ -744,40 +662,6 @@ SetAccessibilityViewportInfo(viewport_info); } -namespace { - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class PdfHasAttachment { - kNo = 0, - kYes = 1, - kMaxValue = kYes, -}; - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class PdfIsTagged { - kNo = 0, - kYes = 1, - kMaxValue = kYes, -}; - -} // namespace - -void PdfViewPluginBase::RecordDocumentMetrics() { - const DocumentMetadata& document_metadata = engine()->GetDocumentMetadata(); - HistogramEnumeration("PDF.Version", document_metadata.version); - HistogramCustomCounts("PDF.PageCount", document_metadata.page_count, 1, - 1000000, 50); - HistogramEnumeration("PDF.HasAttachment", document_metadata.has_attachments - ? PdfHasAttachment::kYes - : PdfHasAttachment::kNo); - HistogramEnumeration("PDF.IsTagged", document_metadata.tagged - ? PdfIsTagged::kYes - : PdfIsTagged::kNo); - HistogramEnumeration("PDF.FormType", document_metadata.form_type); -} - void PdfViewPluginBase::SetZoom(double scale) { double old_zoom = zoom_; zoom_ = scale; @@ -1098,6 +982,97 @@ deferred_invalidates_.clear(); } +void PdfViewPluginBase::SendAttachments() { + const std::vector<DocumentAttachmentInfo>& attachment_infos = + engine()->GetDocumentAttachmentInfoList(); + if (attachment_infos.empty()) + return; + + base::Value attachments(base::Value::Type::LIST); + for (const DocumentAttachmentInfo& attachment_info : attachment_infos) { + // Send `size` as -1 to indicate that the attachment is too large to be + // downloaded. + const int size = attachment_info.size_bytes <= kMaximumSavedFileSize + ? static_cast<int>(attachment_info.size_bytes) + : -1; + + base::Value attachment(base::Value::Type::DICTIONARY); + attachment.SetStringKey("name", attachment_info.name); + attachment.SetIntKey("size", size); + attachment.SetBoolKey("readable", attachment_info.is_readable); + attachments.Append(std::move(attachment)); + } + + base::Value message(base::Value::Type::DICTIONARY); + message.SetStringKey("type", "attachments"); + message.SetKey("attachmentsData", std::move(attachments)); + SendMessage(std::move(message)); +} + +void PdfViewPluginBase::SendBookmarks() { + base::Value bookmarks = engine()->GetBookmarks(); + if (bookmarks.GetList().empty()) + return; + + base::Value message(base::Value::Type::DICTIONARY); + message.SetStringKey("type", "bookmarks"); + message.SetKey("bookmarksData", std::move(bookmarks)); + SendMessage(std::move(message)); +} + +void PdfViewPluginBase::SendMetadata() { + base::Value metadata(base::Value::Type::DICTIONARY); + const DocumentMetadata& document_metadata = engine()->GetDocumentMetadata(); + + const std::string version = FormatPdfVersion(document_metadata.version); + if (!version.empty()) + metadata.SetStringKey("version", version); + + metadata.SetStringKey("fileSize", + ui::FormatBytes(document_metadata.size_bytes)); + + metadata.SetBoolKey("linearized", document_metadata.linearized); + + if (!document_metadata.title.empty()) + metadata.SetStringKey("title", document_metadata.title); + + if (!document_metadata.author.empty()) + metadata.SetStringKey("author", document_metadata.author); + + if (!document_metadata.subject.empty()) + metadata.SetStringKey("subject", document_metadata.subject); + + if (!document_metadata.keywords.empty()) + metadata.SetStringKey("keywords", document_metadata.keywords); + + if (!document_metadata.creator.empty()) + metadata.SetStringKey("creator", document_metadata.creator); + + if (!document_metadata.producer.empty()) + metadata.SetStringKey("producer", document_metadata.producer); + + if (!document_metadata.creation_date.is_null()) { + metadata.SetStringKey("creationDate", base::TimeFormatShortDateAndTime( + document_metadata.creation_date)); + } + + if (!document_metadata.mod_date.is_null()) { + metadata.SetStringKey("modDate", base::TimeFormatShortDateAndTime( + document_metadata.mod_date)); + } + + metadata.SetStringKey("pageSize", + FormatPageSize(engine()->GetUniformPageSizePoints())); + + metadata.SetBoolKey("canSerializeDocument", + IsSaveDataSizeValid(engine()->GetLoadedByteSize())); + + base::Value message(base::Value::Type::DICTIONARY); + message.SetStringKey("type", "metadata"); + message.SetKey("metadataData", std::move(metadata)); + SendMessage(std::move(message)); +} + void PdfViewPluginBase::SendThumbnail(base::Value reply, Thumbnail thumbnail) { const SkBitmap& bitmap = thumbnail.bitmap(); base::Value image_data(base::make_span( @@ -1111,6 +1086,70 @@ SendMessage(std::move(reply)); } +void PdfViewPluginBase::LoadAccessibility() { + accessibility_state_ = AccessibilityState::kLoaded; + AccessibilityDocInfo doc_info; + doc_info.page_count = engine_->GetNumberOfPages(); + doc_info.text_accessible = + engine_->HasPermission(PDFEngine::PERMISSION_COPY_ACCESSIBLE); + doc_info.text_copyable = engine_->HasPermission(PDFEngine::PERMISSION_COPY); + + // A new document layout will trigger the creation of a new accessibility + // tree, so `next_accessibility_page_index_` should be reset to ignore + // outdated asynchronous calls of PrepareAndSetAccessibilityPageInfo(). + next_accessibility_page_index_ = 0; + SetAccessibilityDocInfo(doc_info); + + // If the document contents isn't accessible, don't send anything more. + if (!(engine_->HasPermission(PDFEngine::PERMISSION_COPY) || + engine_->HasPermission(PDFEngine::PERMISSION_COPY_ACCESSIBLE))) { + return; + } + + PrepareAndSetAccessibilityViewportInfo(); + + // Schedule loading the first page. + ScheduleTaskOnMainThread( + kAccessibilityPageDelay, + base::BindOnce(&PdfViewPluginBase::PrepareAndSetAccessibilityPageInfo, + GetWeakPtr()), + 0); +} + +namespace { + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class PdfHasAttachment { + kNo = 0, + kYes = 1, + kMaxValue = kYes, +}; + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class PdfIsTagged { + kNo = 0, + kYes = 1, + kMaxValue = kYes, +}; + +} // namespace + +void PdfViewPluginBase::RecordDocumentMetrics() { + const DocumentMetadata& document_metadata = engine()->GetDocumentMetadata(); + HistogramEnumeration("PDF.Version", document_metadata.version); + HistogramCustomCounts("PDF.PageCount", document_metadata.page_count, 1, + 1000000, 50); + HistogramEnumeration("PDF.HasAttachment", document_metadata.has_attachments + ? PdfHasAttachment::kYes + : PdfHasAttachment::kNo); + HistogramEnumeration("PDF.IsTagged", document_metadata.tagged + ? PdfIsTagged::kYes + : PdfIsTagged::kNo); + HistogramEnumeration("PDF.FormType", document_metadata.form_type); +} + template <typename T> void PdfViewPluginBase::HistogramEnumeration(const char* name, T sample) { if (IsPrintPreview())
diff --git a/pdf/pdf_view_plugin_base.h b/pdf/pdf_view_plugin_base.h index 35242fd3..fbccaba 100644 --- a/pdf/pdf_view_plugin_base.h +++ b/pdf/pdf_view_plugin_base.h
@@ -74,6 +74,7 @@ const std::string& bcc, const std::string& subject, const std::string& body) override; + void DocumentLoadComplete() override; void DocumentLoadProgress(uint32_t available, uint32_t doc_size) override; void FormTextFieldFocusChange(bool in_focus) override; SkColor GetBackgroundColor() override; @@ -158,15 +159,6 @@ // Consumes a token for saving the document. void ConsumeSaveToken(const std::string& token); - // Sends the attachments data. - void SendAttachments(); - - // Sends the bookmarks data. - void SendBookmarks(); - - // Send document metadata data. - void SendMetadata(); - // Sends the loading progress, where `percentage` represents the progress, or // -1 for loading error. void SendLoadingProgress(double percentage); @@ -214,9 +206,6 @@ // Sets the text input type for this plugin based on `in_focus`. virtual void SetFormFieldInFocus(bool in_focus) = 0; - // Starts loading accessibility information. - void LoadAccessibility(); - // Sets the accessibility information about the PDF document in the renderer. virtual void SetAccessibilityDocInfo( const AccessibilityDocInfo& doc_info) = 0; @@ -247,8 +236,19 @@ return size > 0 && size <= kMaximumSavedFileSize; } - // Records metrics about the document metadata. - void RecordDocumentMetrics(); + // Disables browser commands because of restrictions on how the data is to be + // used (i.e. can't copy/print). `content_restrictions` should have its bits + // set by `chrome_pdf::ContentRestriction` enum values. + virtual void SetContentRestrictions(int content_restrictions) = 0; + + // Sends start/stop loading notifications to the plugin's render frame. + // TODO(crbug.com/702993): Evaluate whether these methods are needed when the + // plugin is moved into a renderer process. + virtual void DidStartLoading() = 0; + virtual void DidStopLoading() = 0; + + // Performs tasks necessary when the document is loaded in print preview mode. + virtual void OnPrintPreviewLoaded() = 0; // Records user actions. virtual void UserMetricsRecordAction(const std::string& action) = 0; @@ -327,9 +327,24 @@ // Callback to clear deferred invalidates after painting finishes. void ClearDeferredInvalidates(int32_t /*unused_but_required*/); + // Sends the attachments data. + void SendAttachments(); + + // Sends the bookmarks data. + void SendBookmarks(); + + // Send document metadata data. + void SendMetadata(); + // Sends the thumbnail image data. void SendThumbnail(base::Value reply, Thumbnail thumbnail); + // Starts loading accessibility information. + void LoadAccessibility(); + + // Records metrics about the document metadata. + void RecordDocumentMetrics(); + // Adds a sample to an enumerated histogram and filter out print preview // usage. template <typename T>
diff --git a/pdf/pdf_view_plugin_base_unittest.cc b/pdf/pdf_view_plugin_base_unittest.cc index e2afbc9..9bae332 100644 --- a/pdf/pdf_view_plugin_base_unittest.cc +++ b/pdf/pdf_view_plugin_base_unittest.cc
@@ -113,6 +113,14 @@ (const AccessibilityViewportInfo&), (override)); + MOCK_METHOD(void, SetContentRestrictions, (int), (override)); + + MOCK_METHOD(void, DidStartLoading, (), (override)); + + MOCK_METHOD(void, DidStopLoading, (), (override)); + + MOCK_METHOD(void, OnPrintPreviewLoaded, (), (override)); + MOCK_METHOD(void, UserMetricsRecordAction, (const std::string&), (override)); base::Value sent_message_;
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index 8bf2eb3..0dd22c4 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc
@@ -276,10 +276,6 @@ return {}; } -void PdfViewWebPlugin::DocumentLoadComplete() { - NOTIMPLEMENTED(); -} - void PdfViewWebPlugin::DocumentLoadFailed() { NOTIMPLEMENTED(); } @@ -442,6 +438,22 @@ NOTIMPLEMENTED(); } +void PdfViewWebPlugin::SetContentRestrictions(int content_restrictions) { + NOTIMPLEMENTED(); +} + +void PdfViewWebPlugin::DidStartLoading() { + NOTIMPLEMENTED(); +} + +void PdfViewWebPlugin::DidStopLoading() { + NOTIMPLEMENTED(); +} + +void PdfViewWebPlugin::OnPrintPreviewLoaded() { + NOTIMPLEMENTED(); +} + void PdfViewWebPlugin::UserMetricsRecordAction(const std::string& action) { base::RecordAction(base::UserMetricsAction(action.c_str())); }
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h index d82e7bc..be99abd 100644 --- a/pdf/pdf_view_web_plugin.h +++ b/pdf/pdf_view_web_plugin.h
@@ -79,7 +79,6 @@ std::vector<SearchStringResult> SearchString(const char16_t* string, const char16_t* term, bool case_sensitive) override; - void DocumentLoadComplete() override; void DocumentLoadFailed() override; pp::Instance* GetPluginInstance() override; void DocumentHasUnsupportedFeature(const std::string& feature) override; @@ -129,6 +128,10 @@ AccessibilityPageObjects page_objects) override; void SetAccessibilityViewportInfo( const AccessibilityViewportInfo& viewport_info) override; + void SetContentRestrictions(int content_restrictions) override; + void DidStartLoading() override; + void DidStopLoading() override; + void OnPrintPreviewLoaded() override; void UserMetricsRecordAction(const std::string& action) override; private:
diff --git a/pdf/pdfium/pdfium_assert_matching_enums.cc b/pdf/pdfium/pdfium_assert_matching_enums.cc index 0943ce9..49faf44 100644 --- a/pdf/pdfium/pdfium_assert_matching_enums.cc +++ b/pdf/pdfium/pdfium_assert_matching_enums.cc
@@ -4,6 +4,7 @@ #include "build/build_config.h" #include "pdf/accessibility_structs.h" +#include "pdf/content_restriction.h" #include "pdf/document_metadata.h" #include "pdf/ppapi_migration/input_event_conversions.h" #include "ppapi/c/pp_input_event.h" @@ -394,3 +395,14 @@ PP_PDF_SCROLL_ALIGNMENT_CLOSEST_EDGE); STATIC_ASSERT_ENUM(chrome_pdf::AccessibilityScrollAlignment::kMaxValue, PP_PDF_ACCESSIBILITYSCROLLALIGNMENT_LAST); + +STATIC_ASSERT_ENUM(chrome_pdf::kContentRestrictionCopy, + PP_CONTENT_RESTRICTION_COPY); +STATIC_ASSERT_ENUM(chrome_pdf::kContentRestrictionCut, + PP_CONTENT_RESTRICTION_CUT); +STATIC_ASSERT_ENUM(chrome_pdf::kContentRestrictionPaste, + PP_CONTENT_RESTRICTION_PASTE); +STATIC_ASSERT_ENUM(chrome_pdf::kContentRestrictionPrint, + PP_CONTENT_RESTRICTION_PRINT); +STATIC_ASSERT_ENUM(chrome_pdf::kContentRestrictionSave, + PP_CONTENT_RESTRICTION_SAVE);
diff --git a/printing/printing_context_chromeos.cc b/printing/printing_context_chromeos.cc index b0314d8..5db39a0 100644 --- a/printing/printing_context_chromeos.cc +++ b/printing/printing_context_chromeos.cc
@@ -13,7 +13,6 @@ #include <utility> #include <vector> -#include "base/feature_list.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" @@ -30,7 +29,6 @@ #include "printing/mojom/print.mojom.h" #include "printing/print_job_constants.h" #include "printing/print_settings.h" -#include "printing/printing_features.h" #include "printing/printing_utils.h" #include "printing/units.h"
diff --git a/sandbox/policy/mac/BUILD.gn b/sandbox/policy/mac/BUILD.gn index e93371f..1bd2780 100644 --- a/sandbox/policy/mac/BUILD.gn +++ b/sandbox/policy/mac/BUILD.gn
@@ -11,7 +11,6 @@ "cdm.sb", "common.sb", "gpu.sb", - "gpu_v2.sb", "nacl_loader.sb", "network.sb", "ppapi.sb",
diff --git a/sandbox/policy/mac/gpu.sb b/sandbox/policy/mac/gpu.sb index dc0cd5f609..7d93ec13 100644 --- a/sandbox/policy/mac/gpu.sb +++ b/sandbox/policy/mac/gpu.sb
@@ -1,91 +1,145 @@ -;; -;; Copyright (c) 2011 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. -;; +; 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. -; *** The contents of the V1 sandbox common.sb are below. *** +; --- The contents of common.sb implicitly included here. --- -(version 1) +(deny default (with partial-symbolication)) +(debug deny) -; Helper function to check if a param is set to true. -(define (param-true? str) (string=? (param str) "TRUE")) +; Allow cf prefs to work. +(allow user-preference-read) -; Helper function to determine if a parameter is defined or not. -(define (param-defined? str) (string? (param str))) - -; Define constants for all of the parameter strings passed in. -(define bundle-version-path "BUNDLE_VERSION_PATH") -(define disable-sandbox-denial-logging "DISABLE_SANDBOX_DENIAL_LOGGING") -(define enable-logging "ENABLE_LOGGING") -(define homedir-as-literal "USER_HOMEDIR_AS_LITERAL") -(define macos-1013 "MACOS_1013") -(define field-trial-server-name "FIELD_TRIAL_SERVER_NAME") - -; Backwards compatibility for 10.11 -(if (not (defined? 'iokit-registry-entry-class)) - (define iokit-registry-entry-class iokit-user-client-class)) - -; Consumes a subpath and appends it to the user's homedir path. -(define (user-homedir-path subpath) - (string-append (param homedir-as-literal) subpath)) - -; DISABLE_SANDBOX_DENIAL_LOGGING turns off log messages in the system log. -(if (param-true? disable-sandbox-denial-logging) - (deny default (with no-log)) - (deny default)) - -; Support for programmatically enabling verbose debugging. -(if (param-true? enable-logging) (debug deny)) - -(allow mach-lookup (global-name (param field-trial-server-name))) - -; Allow sending signals to self - https://crbug.com/20370 -(allow signal (target self)) - -; Needed for full-page-zoomed controls - https://crbug.com/11325 -(allow sysctl-read) - -; Loading System Libraries. -(allow file-read* - (subpath "/System/Library/Frameworks") - (subpath "/System/Library/PrivateFrameworks") - (subpath "/System/Library/CoreServices")) +(allow-cvms-blobs) (allow ipc-posix-shm) -; Allow direct access to /dev/urandom, similar to Linux/POSIX, to allow -; third party code (eg: bits of Adobe Flash and NSS) to function properly. -(allow file-read-data file-read-metadata (literal "/dev/urandom")) - -; *** The contents of the V1 sandbox gpu.sb are below. *** +(define disable-metal-shader-cache "DISABLE_METAL_SHADER_CACHE") ; Allow communication between the GPU process and the UI server. -(allow mach-lookup (global-name "com.apple.tsm.uiserver")) +(allow mach-lookup + (global-name "com.apple.bsd.dirhelper") + (global-name "com.apple.CARenderServer") + (global-name "com.apple.cfprefsd.agent") + (global-name "com.apple.cfprefsd.daemon") + (global-name "com.apple.CoreServices.coreservicesd") + (global-name "com.apple.coreservices.launchservicesd") + (global-name "com.apple.cvmsServ") + (global-name "com.apple.gpumemd.source") + (global-name "com.apple.lsd.mapdb") + (global-name "com.apple.lsd.modifydb") + (global-name "com.apple.powerlog.plxpclogger.xpc") + (global-name "com.apple.PowerManagement.control") + (global-name "com.apple.SecurityServer") + (global-name "com.apple.system.notification_center") + (global-name "com.apple.system.opendirectoryd.membership") ; https://crbug.com/1126350#c5 + (global-name "com.apple.tsm.uiserver") + (global-name "com.apple.windowserver.active") +) -(allow file-read-metadata (literal "/")) +; Needed for metal decoding - https://crbug.com/957217 +(if (>= os-version 1014) + (allow mach-lookup (xpc-service-name "com.apple.MTLCompilerService")) +) -; Needed for WebGL - crbug.com/75343 +; Needed for VideoToolbox H.264 SW and VP9 decoding - https://crbug.com/1113936 +(if (>= os-version 1016) + (begin + (allow mach-lookup (global-name "com.apple.trustd.agent")) + (allow file-read* (path "/Library/Preferences/com.apple.security.plist")) + ) +) + +; Needed for WebGL - https://crbug.com/75343 (allow iokit-open (iokit-connection "IOAccelerator") + (iokit-user-client-class "AGPMClient") + (iokit-user-client-class "AppleGraphicsControlClient") + (iokit-user-client-class "AppleGraphicsPolicyClient") + (iokit-user-client-class "AppleIntelMEUserClient") + (iokit-user-client-class "AppleMGPUPowerControlClient") + (iokit-user-client-class "AppleSNBFBUserClient") (iokit-user-client-class "IOAccelerationUserClient") (iokit-user-client-class "IOFramebufferSharedUserClient") - (iokit-user-client-class "AppleGraphicsControlClient") - (iokit-user-client-class "AGPMClient") (iokit-user-client-class "IOHIDParamUserClient") - (iokit-user-client-class "RootDomainUserClient") (iokit-user-client-class "IOSurfaceRootUserClient") - (iokit-user-client-class "IOSurfaceSendRight")) + (iokit-user-client-class "IOSurfaceSendRight") + (iokit-user-client-class "RootDomainUserClient") +) -; https://crbug.com/515280 -(allow file-read* (subpath "/System/Library/Extensions")) +(allow iokit-set-properties + (require-all (iokit-connection "IODisplay") + (require-any (iokit-property "brightness") + (iokit-property "linear-brightness") + (iokit-property "commit") + (iokit-property "rgcs") + (iokit-property "ggcs") + (iokit-property "bgcs") +))) + +(allow ipc-posix-shm-read-data + (ipc-posix-name "apple.shm.notification_center")) + ; Needed for VideoToolbox usage - https://crbug.com/767037 -(allow mach-lookup (global-name "com.apple.coremedia.videodecoder")) +(if (>= os-version 1013) + (allow mach-lookup + (xpc-service-name "com.apple.coremedia.videodecoder") + (xpc-service-name "com.apple.coremedia.videoencoder") + (xpc-service-name-regex #"\.apple-extension-service$") +)) -; Needed for 10.14.5+ - https://crbug.com/957217 -(if (defined? 'xpc-service-name) - (allow mach-lookup (xpc-service-name "com.apple.MTLCompilerService"))) +(allow sysctl-read + (sysctl-name "hw.busfrequency_max") + (sysctl-name "hw.cachelinesize") + (sysctl-name "hw.logicalcpu_max") + (sysctl-name "hw.memsize") + (sysctl-name "hw.model") + (sysctl-name "kern.osvariant_status") +) -; Needed for GPU process to fallback to SwiftShader - https://crbug.com/897914 -(allow file-read-data file-read-metadata (subpath (param bundle-version-path))) +(allow file-read-data + (path "/Library/MessageTracer/SubmitDiagInfo.default.domains.searchtree") + (path "/System/Library/MessageTracer/SubmitDiagInfo.default.domains.searchtree") + (regex (user-homedir-path #"/Library/Preferences/(.*/)?com\.apple\.driver\..*\.plist")) + (regex (user-homedir-path #"/Library/Preferences/ByHost/com.apple.AppleGVA.*")) +) + +(allow file-read* + (path (user-homedir-path "/Library/Preferences")) ; List contents of preference directories https://crbug.com/1126350#c14. + (path (user-homedir-path "/Library/Preferences/ByHost")) + (subpath "/Library/GPUBundles") + (subpath "/Library/Video/Plug-Ins") + (subpath "/System/Library/ColorSync/Profiles") + (subpath "/System/Library/CoreServices/RawCamera.bundle") + (subpath "/System/Library/Extensions") ; https://crbug.com/515280 + (subpath "/System/Library/Video/Plug-Ins") +) + +; crbug.com/980134 +(allow file-read* file-write* + (subpath (param darwin-user-cache-dir)) + (subpath (param darwin-user-dir)) + (subpath (param darwin-user-temp-dir)) +) + +(if (param-true? filter-syscalls-debug) + (when (defined? 'syscall-unix) + (deny syscall-unix (with send-signal SIGSYS)) + (allow syscall-unix + (syscall-number SYS_csrctl) + (syscall-number SYS_getentropy) + (syscall-number SYS_getxattr) + (syscall-number SYS_kdebug_typefilter) + (syscall-number SYS_sigaltstack) + (syscall-number SYS_write) + (syscall-number SYS_write_nocancel) +))) + +; crbug.com/1159113 +(if (param-true? disable-metal-shader-cache) + (let ((metal-cache-dir (subpath (string-append (param darwin-user-cache-dir) + "/com.apple.metal")))) + (deny file-read* metal-cache-dir) + (deny file-write* metal-cache-dir)) +)
diff --git a/sandbox/policy/mac/gpu_v2.sb b/sandbox/policy/mac/gpu_v2.sb deleted file mode 100644 index 7d93ec13..0000000 --- a/sandbox/policy/mac/gpu_v2.sb +++ /dev/null
@@ -1,145 +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. - -; --- The contents of common.sb implicitly included here. --- - -(deny default (with partial-symbolication)) -(debug deny) - -; Allow cf prefs to work. -(allow user-preference-read) - -(allow-cvms-blobs) - -(allow ipc-posix-shm) - -(define disable-metal-shader-cache "DISABLE_METAL_SHADER_CACHE") - -; Allow communication between the GPU process and the UI server. -(allow mach-lookup - (global-name "com.apple.bsd.dirhelper") - (global-name "com.apple.CARenderServer") - (global-name "com.apple.cfprefsd.agent") - (global-name "com.apple.cfprefsd.daemon") - (global-name "com.apple.CoreServices.coreservicesd") - (global-name "com.apple.coreservices.launchservicesd") - (global-name "com.apple.cvmsServ") - (global-name "com.apple.gpumemd.source") - (global-name "com.apple.lsd.mapdb") - (global-name "com.apple.lsd.modifydb") - (global-name "com.apple.powerlog.plxpclogger.xpc") - (global-name "com.apple.PowerManagement.control") - (global-name "com.apple.SecurityServer") - (global-name "com.apple.system.notification_center") - (global-name "com.apple.system.opendirectoryd.membership") ; https://crbug.com/1126350#c5 - (global-name "com.apple.tsm.uiserver") - (global-name "com.apple.windowserver.active") -) - -; Needed for metal decoding - https://crbug.com/957217 -(if (>= os-version 1014) - (allow mach-lookup (xpc-service-name "com.apple.MTLCompilerService")) -) - -; Needed for VideoToolbox H.264 SW and VP9 decoding - https://crbug.com/1113936 -(if (>= os-version 1016) - (begin - (allow mach-lookup (global-name "com.apple.trustd.agent")) - (allow file-read* (path "/Library/Preferences/com.apple.security.plist")) - ) -) - -; Needed for WebGL - https://crbug.com/75343 -(allow iokit-open - (iokit-connection "IOAccelerator") - (iokit-user-client-class "AGPMClient") - (iokit-user-client-class "AppleGraphicsControlClient") - (iokit-user-client-class "AppleGraphicsPolicyClient") - (iokit-user-client-class "AppleIntelMEUserClient") - (iokit-user-client-class "AppleMGPUPowerControlClient") - (iokit-user-client-class "AppleSNBFBUserClient") - (iokit-user-client-class "IOAccelerationUserClient") - (iokit-user-client-class "IOFramebufferSharedUserClient") - (iokit-user-client-class "IOHIDParamUserClient") - (iokit-user-client-class "IOSurfaceRootUserClient") - (iokit-user-client-class "IOSurfaceSendRight") - (iokit-user-client-class "RootDomainUserClient") -) - -(allow iokit-set-properties - (require-all (iokit-connection "IODisplay") - (require-any (iokit-property "brightness") - (iokit-property "linear-brightness") - (iokit-property "commit") - (iokit-property "rgcs") - (iokit-property "ggcs") - (iokit-property "bgcs") -))) - -(allow ipc-posix-shm-read-data - (ipc-posix-name "apple.shm.notification_center")) - - -; Needed for VideoToolbox usage - https://crbug.com/767037 -(if (>= os-version 1013) - (allow mach-lookup - (xpc-service-name "com.apple.coremedia.videodecoder") - (xpc-service-name "com.apple.coremedia.videoencoder") - (xpc-service-name-regex #"\.apple-extension-service$") -)) - -(allow sysctl-read - (sysctl-name "hw.busfrequency_max") - (sysctl-name "hw.cachelinesize") - (sysctl-name "hw.logicalcpu_max") - (sysctl-name "hw.memsize") - (sysctl-name "hw.model") - (sysctl-name "kern.osvariant_status") -) - -(allow file-read-data - (path "/Library/MessageTracer/SubmitDiagInfo.default.domains.searchtree") - (path "/System/Library/MessageTracer/SubmitDiagInfo.default.domains.searchtree") - (regex (user-homedir-path #"/Library/Preferences/(.*/)?com\.apple\.driver\..*\.plist")) - (regex (user-homedir-path #"/Library/Preferences/ByHost/com.apple.AppleGVA.*")) -) - -(allow file-read* - (path (user-homedir-path "/Library/Preferences")) ; List contents of preference directories https://crbug.com/1126350#c14. - (path (user-homedir-path "/Library/Preferences/ByHost")) - (subpath "/Library/GPUBundles") - (subpath "/Library/Video/Plug-Ins") - (subpath "/System/Library/ColorSync/Profiles") - (subpath "/System/Library/CoreServices/RawCamera.bundle") - (subpath "/System/Library/Extensions") ; https://crbug.com/515280 - (subpath "/System/Library/Video/Plug-Ins") -) - -; crbug.com/980134 -(allow file-read* file-write* - (subpath (param darwin-user-cache-dir)) - (subpath (param darwin-user-dir)) - (subpath (param darwin-user-temp-dir)) -) - -(if (param-true? filter-syscalls-debug) - (when (defined? 'syscall-unix) - (deny syscall-unix (with send-signal SIGSYS)) - (allow syscall-unix - (syscall-number SYS_csrctl) - (syscall-number SYS_getentropy) - (syscall-number SYS_getxattr) - (syscall-number SYS_kdebug_typefilter) - (syscall-number SYS_sigaltstack) - (syscall-number SYS_write) - (syscall-number SYS_write_nocancel) -))) - -; crbug.com/1159113 -(if (param-true? disable-metal-shader-cache) - (let ((metal-cache-dir (subpath (string-append (param darwin-user-cache-dir) - "/com.apple.metal")))) - (deny file-read* metal-cache-dir) - (deny file-write* metal-cache-dir)) -)
diff --git a/sandbox/policy/mac/sandbox_mac.h b/sandbox/policy/mac/sandbox_mac.h index 7740d30..76bdc20 100644 --- a/sandbox/policy/mac/sandbox_mac.h +++ b/sandbox/policy/mac/sandbox_mac.h
@@ -5,7 +5,9 @@ #ifndef SANDBOX_POLICY_MAC_SANDBOX_MAC_H_ #define SANDBOX_POLICY_MAC_SANDBOX_MAC_H_ -#include "base/gtest_prod_util.h" +#include <string> + +#include "base/files/file_path.h" #include "base/macros.h" #include "sandbox/policy/export.h" #include "sandbox/policy/sandbox_type.h" @@ -19,20 +21,6 @@ class SANDBOX_POLICY_EXPORT SandboxMac { public: - // Warm up System APIs that empirically need to be accessed before the - // sandbox is turned on. |sandbox_type| is the type of sandbox to warm up. - // Valid |sandbox_type| values are defined by the enum SandboxType, or can be - // defined by the embedder via - // ContentClient::GetSandboxProfileForProcessType(). - static void Warmup(SandboxType sandbox_type); - - // Turns on the OS X sandbox for this process. - // |sandbox_type| - type of Sandbox to use. See SandboxWarmup() for legal - // values. - // - // Returns true on success, false if an error occurred enabling the sandbox. - static bool Enable(SandboxType sandbox_type); - // Convert provided path into a "canonical" path matching what the Sandbox // expects i.e. one without symlinks. // This path is not necessarily unique e.g. in the face of hardlinks. @@ -55,18 +43,10 @@ static const char* kSandboxLoggingPathAsLiteral; static const char* kSandboxOSVersion; - // TODO(kerrnel): this is only for the legacy sandbox. - static const char* kSandboxMacOS1013; - static const char* kSandboxFieldTrialSeverName; - static const char* kSandboxBundleVersionPath; static const char* kSandboxDisableMetalShaderCache; private: - FRIEND_TEST_ALL_PREFIXES(MacDirAccessSandboxTest, StringEscape); - FRIEND_TEST_ALL_PREFIXES(MacDirAccessSandboxTest, RegexEscape); - FRIEND_TEST_ALL_PREFIXES(MacDirAccessSandboxTest, SandboxAccess); - DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxMac); };
diff --git a/sandbox/policy/mac/sandbox_mac.mm b/sandbox/policy/mac/sandbox_mac.mm index e7fe9cb0c..f63a70a 100644 --- a/sandbox/policy/mac/sandbox_mac.mm +++ b/sandbox/policy/mac/sandbox_mac.mm
@@ -4,44 +4,18 @@ #include "sandbox/policy/mac/sandbox_mac.h" -#import <Cocoa/Cocoa.h> -#include <stddef.h> -#include <stdint.h> - -#include <CoreFoundation/CFTimeZone.h> -#include <signal.h> +#include <fcntl.h> #include <sys/param.h> -#include <algorithm> -#include <iterator> -#include <map> #include <string> -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/files/file_util.h" #include "base/files/scoped_file.h" -#include "base/mac/bundle_locations.h" -#include "base/mac/foundation_util.h" -#include "base/mac/mac_util.h" -#include "base/mac/mach_port_rendezvous.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/mac/scoped_nsobject.h" -#include "base/rand_util.h" -#include "base/stl_util.h" -#include "base/strings/string_piece.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/strings/sys_string_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/system/sys_info.h" -#include "sandbox/mac/sandbox_compiler.h" +#include "base/logging.h" +#include "base/posix/eintr_wrapper.h" #include "sandbox/policy/mac/audio.sb.h" #include "sandbox/policy/mac/cdm.sb.h" #include "sandbox/policy/mac/common.sb.h" #include "sandbox/policy/mac/gpu.sb.h" -#include "sandbox/policy/mac/gpu_v2.sb.h" #include "sandbox/policy/mac/nacl_loader.sb.h" #include "sandbox/policy/mac/network.sb.h" #include "sandbox/policy/mac/ppapi.sb.h" @@ -50,13 +24,10 @@ #include "sandbox/policy/mac/renderer.sb.h" #include "sandbox/policy/mac/speech_recognition.sb.h" #include "sandbox/policy/mac/utility.sb.h" -#include "sandbox/policy/sandbox_type.h" -#include "sandbox/policy/switches.h" namespace sandbox { namespace policy { -// Static variable declarations. const char* SandboxMac::kSandboxBrowserPID = "BROWSER_PID"; const char* SandboxMac::kSandboxBundlePath = "BUNDLE_PATH"; const char* SandboxMac::kSandboxChromeBundleId = "BUNDLE_ID"; @@ -70,148 +41,10 @@ const char* SandboxMac::kSandboxHomedirAsLiteral = "USER_HOMEDIR_AS_LITERAL"; const char* SandboxMac::kSandboxLoggingPathAsLiteral = "LOG_FILE_PATH"; const char* SandboxMac::kSandboxOSVersion = "OS_VERSION"; -const char* SandboxMac::kSandboxMacOS1013 = "MACOS_1013"; -const char* SandboxMac::kSandboxFieldTrialSeverName = "FIELD_TRIAL_SERVER_NAME"; const char* SandboxMac::kSandboxBundleVersionPath = "BUNDLE_VERSION_PATH"; const char* SandboxMac::kSandboxDisableMetalShaderCache = "DISABLE_METAL_SHADER_CACHE"; -// Warm up System APIs that empirically need to be accessed before the Sandbox -// is turned on. -// This method is layed out in blocks, each one containing a separate function -// that needs to be warmed up. The OS version on which we found the need to -// enable the function is also noted. -// This function is tested on the following OS versions: -// 10.5.6, 10.6.0 - -// static -void SandboxMac::Warmup(SandboxType sandbox_type) { - DCHECK_EQ(sandbox_type, SandboxType::kGpu); - - @autoreleasepool { - { // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6 - base::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace( - CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); - - // Allocate a 1x1 image. - char data[4]; - base::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate( - data, 1, 1, 8, 1 * 4, rgb_colorspace, - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - - // Load in the color profiles we'll need (as a side effect). - ignore_result(base::mac::GetSRGBColorSpace()); - ignore_result(base::mac::GetSystemColorSpace()); - - // CGColorSpaceCreateSystemDefaultCMYK - 10.6 - base::ScopedCFTypeRef<CGColorSpaceRef> cmyk_colorspace( - CGColorSpaceCreateWithName(kCGColorSpaceGenericCMYK)); - } - - { // localtime() - 10.5.6 - time_t tv = {0}; - localtime(&tv); - } - - { // Gestalt() tries to read - // /System/Library/CoreServices/SystemVersion.plist - // on 10.5.6 - int32_t tmp; - base::SysInfo::OperatingSystemVersionNumbers(&tmp, &tmp, &tmp); - } - - { // CGImageSourceGetStatus() - 10.6 - // Create a png with just enough data to get everything warmed up... - char png_header[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; - NSData* data = [NSData dataWithBytes:png_header - length:base::size(png_header)]; - base::ScopedCFTypeRef<CGImageSourceRef> img( - CGImageSourceCreateWithData((CFDataRef)data, NULL)); - CGImageSourceGetStatus(img); - } - - { - // Allow access to /dev/urandom. - base::GetUrandomFD(); - } - - { // IOSurfaceLookup() - 10.7 - // Needed by zero-copy texture update framework - crbug.com/323338 - base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceLookup(0)); - } - } -} - -// Load the appropriate template for the given sandbox type. -// Returns the template as a string or an empty string on error. -std::string LoadSandboxTemplate(SandboxType sandbox_type) { - DCHECK_EQ(sandbox_type, SandboxType::kGpu); - return kSeatbeltPolicyString_gpu; -} - -// Turns on the OS X sandbox for this process. - -// static -bool SandboxMac::Enable(SandboxType sandbox_type) { - DCHECK_EQ(sandbox_type, SandboxType::kGpu); - - std::string sandbox_data = LoadSandboxTemplate(sandbox_type); - if (sandbox_data.empty()) - return false; - - SandboxCompiler compiler(sandbox_data); - - // Enable verbose logging if enabled on the command line. (See common.sb - // for details). - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - bool enable_logging = - command_line->HasSwitch(switches::kEnableSandboxLogging); - if (!compiler.InsertBooleanParam(kSandboxEnableLogging, enable_logging)) - return false; - - // Without this, the sandbox will print a message to the system log every - // time it denies a request. This floods the console with useless spew. - if (!compiler.InsertBooleanParam(kSandboxDisableDenialLogging, - !enable_logging)) - return false; - - // Splice the path of the user's home directory into the sandbox profile - // (see renderer.sb for details). - std::string home_dir = [NSHomeDirectory() fileSystemRepresentation]; - base::FilePath home_dir_canonical = - GetCanonicalPath(base::FilePath(home_dir)); - - if (!compiler.InsertStringParam(kSandboxHomedirAsLiteral, - home_dir_canonical.value())) { - return false; - } - - if (!compiler.InsertStringParam( - kSandboxFieldTrialSeverName, - base::MachPortRendezvousClient::GetBootstrapName())) { - return false; - } - - bool macos_1013 = base::mac::IsOS10_13(); - if (!compiler.InsertBooleanParam(kSandboxMacOS1013, macos_1013)) - return false; - - if (sandbox_type == SandboxType::kGpu) { - base::FilePath bundle_path = - SandboxMac::GetCanonicalPath(base::mac::FrameworkBundlePath()); - if (!compiler.InsertStringParam(kSandboxBundleVersionPath, - bundle_path.value())) - return false; - } - - // Initialize sandbox. - std::string error_str; - bool success = compiler.CompileAndApplyProfile(&error_str); - DLOG_IF(FATAL, !success) << "Failed to initialize sandbox: " << error_str; - return success; -} - // static base::FilePath SandboxMac::GetCanonicalPath(const base::FilePath& path) { base::ScopedFD fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); @@ -241,7 +74,7 @@ profile += kSeatbeltPolicyString_cdm; break; case SandboxType::kGpu: - profile += kSeatbeltPolicyString_gpu_v2; + profile += kSeatbeltPolicyString_gpu; break; case SandboxType::kNaClLoader: profile += kSeatbeltPolicyString_nacl_loader;
diff --git a/sandbox/policy/sandbox.cc b/sandbox/policy/sandbox.cc index 95482e8..449ee4f 100644 --- a/sandbox/policy/sandbox.cc +++ b/sandbox/policy/sandbox.cc
@@ -18,7 +18,6 @@ #if defined(OS_MAC) #include "sandbox/mac/seatbelt.h" -#include "sandbox/policy/mac/sandbox_mac.h" #endif // defined(OS_MAC) #if defined(OS_WIN) @@ -39,20 +38,6 @@ } #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) -#if defined(OS_MAC) -bool Sandbox::Initialize(SandboxType sandbox_type, base::OnceClosure hook) { - // Warm up APIs before turning on the sandbox. - SandboxMac::Warmup(sandbox_type); - - // Execute the post warmup callback. - if (!hook.is_null()) - std::move(hook).Run(); - - // Actually sandbox the process. - return SandboxMac::Enable(sandbox_type); -} -#endif // defined(OS_MAC) - #if defined(OS_WIN) bool Sandbox::Initialize(SandboxType sandbox_type, SandboxInterfaceInfo* sandbox_info) {
diff --git a/sandbox/policy/sandbox.h b/sandbox/policy/sandbox.h index c842e1d..e7c20ed 100644 --- a/sandbox/policy/sandbox.h +++ b/sandbox/policy/sandbox.h
@@ -13,10 +13,6 @@ #include "sandbox/policy/linux/sandbox_linux.h" #endif -#if defined(OS_MAC) -#include "base/callback.h" -#endif // defined(OS_MAC) - namespace sandbox { struct SandboxInterfaceInfo; } // namespace sandbox @@ -40,14 +36,6 @@ const SandboxLinux::Options& options); #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) -#if defined(OS_MAC) - // Initialize the sandbox of |sandbox_type|. Runs |post_warmup_hook| if - // non-empty after performing any sandbox warmup but immediately before - // engaging the sandbox. Return true on success, false otherwise. - static bool Initialize(SandboxType sandbox_type, - base::OnceClosure post_warmup_hook); -#endif // defined(OS_MAC) - #if defined(OS_WIN) static bool Initialize(SandboxType sandbox_type, SandboxInterfaceInfo* sandbox_info);
diff --git a/services/viz/public/cpp/compositing/compositor_frame_transition_directive_mojom_traits.cc b/services/viz/public/cpp/compositing/compositor_frame_transition_directive_mojom_traits.cc index f428bc9..cc626e4 100644 --- a/services/viz/public/cpp/compositing/compositor_frame_transition_directive_mojom_traits.cc +++ b/services/viz/public/cpp/compositing/compositor_frame_transition_directive_mojom_traits.cc
@@ -135,19 +135,14 @@ viz::CompositorFrameTransitionDirective::Type type; viz::CompositorFrameTransitionDirective::Effect effect; - base::TimeDelta duration; std::vector<viz::CompositorRenderPassId> shared_render_pass_ids; if (!data.ReadType(&type) || !data.ReadEffect(&effect) || - !data.ReadDuration(&duration) || !data.ReadSharedRenderPassIds(&shared_render_pass_ids)) { return false; } - if (duration > viz::CompositorFrameTransitionDirective::kMaxDuration) - return false; - *out = viz::CompositorFrameTransitionDirective( - sequence_id, type, effect, duration, std::move(shared_render_pass_ids)); + sequence_id, type, effect, std::move(shared_render_pass_ids)); return true; }
diff --git a/services/viz/public/cpp/compositing/compositor_frame_transition_directive_mojom_traits.h b/services/viz/public/cpp/compositing/compositor_frame_transition_directive_mojom_traits.h index 4e1ef8b..06604401 100644 --- a/services/viz/public/cpp/compositing/compositor_frame_transition_directive_mojom_traits.h +++ b/services/viz/public/cpp/compositing/compositor_frame_transition_directive_mojom_traits.h
@@ -38,11 +38,6 @@ template <> struct StructTraits<viz::mojom::CompositorFrameTransitionDirectiveDataView, viz::CompositorFrameTransitionDirective> { - static base::TimeDelta duration( - const viz::CompositorFrameTransitionDirective& directive) { - return directive.duration(); - } - static uint32_t sequence_id( const viz::CompositorFrameTransitionDirective& directive) { return directive.sequence_id();
diff --git a/services/viz/public/mojom/compositing/compositor_frame_transition_directive.mojom b/services/viz/public/mojom/compositing/compositor_frame_transition_directive.mojom index e2dc3d4..68b0445b 100644 --- a/services/viz/public/mojom/compositing/compositor_frame_transition_directive.mojom +++ b/services/viz/public/mojom/compositing/compositor_frame_transition_directive.mojom
@@ -4,7 +4,6 @@ module viz.mojom; -import "mojo/public/mojom/base/time.mojom"; import "services/viz/public/mojom/compositing/compositor_render_pass_id.mojom"; enum CompositorFrameTransitionDirectiveType { @@ -36,7 +35,5 @@ CompositorFrameTransitionDirectiveEffect effect; - mojo_base.mojom.TimeDelta duration; - array<CompositorRenderPassId> shared_render_pass_ids; };
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 4a88388..aa272e67 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -5216,1653 +5216,6 @@ } ] }, - "Mac10.13 Tests (dbg)": { - "gtest_tests": [ - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "absl_hardening_tests", - "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "accessibility_unittests", - "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/" - }, - { - "args": [ - "angle_unittests" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_unittests", - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/", - "use_isolated_scripts_api": true - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "app_shell_unittests", - "test_id_prefix": "ninja://extensions/shell:app_shell_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "base_unittests", - "test_id_prefix": "ninja://base:base_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "base_util_unittests", - "test_id_prefix": "ninja://base/util:base_util_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_common_unittests", - "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_fuzzer_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_fuzzer_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_heap_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_platform_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webkit_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "blink_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "boringssl_crypto_tests", - "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "boringssl_ssl_tests", - "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 40 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--gtest_filter=-*UsingRealWebcam*" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "capture_unittests", - "test_id_prefix": "ninja://media/capture:capture_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cast_unittests", - "test_id_prefix": "ninja://media/cast:cast_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cc_unittests", - "test_id_prefix": "ninja://cc:cc_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chrome_app_unittests", - "test_id_prefix": "ninja://chrome/test:chrome_app_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "chromedriver_unittests", - "test_id_prefix": "ninja://chrome/test/chromedriver:chromedriver_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "color_unittests", - "test_id_prefix": "ninja://ui/color:color_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_browsertests", - "test_id_prefix": "ninja://components:components_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test": "content_browsertests", - "test_id_prefix": "ninja://content/test:content_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "content_nocompile_tests", - "test_id_prefix": "ninja://content/test:content_nocompile_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "content_unittests", - "test_id_prefix": "ninja://content/test:content_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "crashpad_tests", - "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cronet_tests", - "test_id_prefix": "ninja://components/cronet:cronet_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "cronet_unittests", - "test_id_prefix": "ninja://components/cronet:cronet_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "crypto_unittests", - "test_id_prefix": "ninja://crypto:crypto_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "device_unittests", - "test_id_prefix": "ninja://device:device_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "display_unittests", - "test_id_prefix": "ninja://ui/display:display_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "events_unittests", - "test_id_prefix": "ninja://ui/events:events_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "extensions_browsertests", - "test_id_prefix": "ninja://extensions:extensions_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "extensions_unittests", - "test_id_prefix": "ninja://extensions:extensions_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "filesystem_service_unittests", - "test_id_prefix": "ninja://components/services/filesystem:filesystem_service_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gcm_unit_tests", - "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gfx_unittests", - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gin_unittests", - "test_id_prefix": "ninja://gin:gin_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "google_apis_unittests", - "test_id_prefix": "ninja://google_apis:google_apis_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gpu_unittests", - "test_id_prefix": "ninja://gpu:gpu_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "gwp_asan_unittests", - "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "headless_browsertests", - "test_id_prefix": "ninja://headless:headless_browsertests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "headless_unittests", - "test_id_prefix": "ninja://headless:headless_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ipc_tests", - "test_id_prefix": "ninja://ipc:ipc_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "jingle_unittests", - "test_id_prefix": "ninja://jingle:jingle_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "latency_unittests", - "test_id_prefix": "ninja://ui/latency:latency_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "libjingle_xmpp_unittests", - "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "liburlpattern_unittests", - "test_id_prefix": "ninja://third_party/liburlpattern:liburlpattern_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "media_blink_unittests", - "test_id_prefix": "ninja://media/blink:media_blink_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "media_unittests", - "test_id_prefix": "ninja://media:media_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "message_center_unittests", - "test_id_prefix": "ninja://ui/message_center:message_center_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "midi_unittests", - "test_id_prefix": "ninja://media/midi:midi_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "mojo_unittests", - "test_id_prefix": "ninja://mojo:mojo_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "nacl_loader_unittests", - "test_id_prefix": "ninja://components/nacl/loader:nacl_loader_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "native_theme_unittests", - "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "net_unittests", - "test_id_prefix": "ninja://net:net_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "openscreen_unittests", - "test_id_prefix": "ninja://chrome/browser/media/router:openscreen_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "pdf_unittests", - "test_id_prefix": "ninja://pdf:pdf_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "perfetto_unittests", - "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ppapi_unittests", - "test_id_prefix": "ninja://ppapi:ppapi_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "printing_unittests", - "test_id_prefix": "ninja://printing:printing_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "remoting_unittests", - "test_id_prefix": "ninja://remoting:remoting_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sandbox_mac_unittests", - "test_id_prefix": "ninja://sandbox/mac:sandbox_mac_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "service_manager_unittests", - "test_id_prefix": "ninja://services/service_manager/tests:service_manager_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "services_unittests", - "test_id_prefix": "ninja://services:services_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "shell_dialogs_unittests", - "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "skia_unittests", - "test_id_prefix": "ninja://skia:skia_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "snapshot_unittests", - "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sql_unittests", - "test_id_prefix": "ninja://sql:sql_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "storage_unittests", - "test_id_prefix": "ninja://storage:storage_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "sync_integration_tests", - "test_id_prefix": "ninja://chrome/test:sync_integration_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ui_base_unittests", - "test_id_prefix": "ninja://ui/base:ui_base_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "ui_touch_selection_unittests", - "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "unit_tests", - "test_id_prefix": "ninja://chrome/test:unit_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "updater_tests", - "test_id_prefix": "ninja://chrome/updater:updater_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "url_unittests", - "test_id_prefix": "ninja://url:url_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "views_unittests", - "test_id_prefix": "ninja://ui/views:views_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "viz_unittests", - "test_id_prefix": "ninja://components/viz:viz_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "wtf_unittests", - "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "xr_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "xr_browser_tests", - "test_id_prefix": "ninja://chrome/test:xr_browser_tests/" - }, - { - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "zlib_unittests", - "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/" - } - ], - "isolated_scripts": [ - { - "isolate_name": "blink_python_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "blink_python_tests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://:blink_python_tests/" - }, - { - "args": [ - "--num-retries=3", - "--debug" - ], - "isolate_name": "blink_web_tests", - "merge": { - "args": [ - "--verbose" - ], - "script": "//third_party/blink/tools/merge_web_test_results.py" - }, - "name": "blink_web_tests", - "resultdb": { - "enable": true - }, - "results_handler": "layout tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 25 - }, - "test_id_prefix": "ninja://:blink_web_tests/" - }, - { - "isolate_name": "content_shell_crash_test", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "content_shell_crash_test", - "resultdb": { - "enable": true, - "result_format": "single" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://content/shell:content_shell_crash_test/" - }, - { - "isolate_name": "flatbuffers_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "flatbuffers_unittests", - "resultdb": { - "enable": true, - "result_format": "single" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/flatbuffers:flatbuffers_unittests/" - }, - { - "isolate_name": "grit_python_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "grit_python_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://tools/grit:grit_python_unittests/" - }, - { - "isolate_name": "metrics_python_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "metrics_python_tests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://tools/metrics:metrics_python_tests/" - }, - { - "args": [ - "--pageset-repeat=1", - "--test-shard-map-filename=smoke_test_benchmark_shard_map.json", - "--browser=debug" - ], - "isolate_name": "performance_test_suite", - "merge": { - "args": [ - "--smoke-test-mode" - ], - "script": "//tools/perf/process_perf_results.py" - }, - "name": "performance_test_suite", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "hard_timeout": 960, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test_id_prefix": "ninja://chrome/test:performance_test_suite/" - }, - { - "isolate_name": "telemetry_gpu_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_gpu_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_gpu_unittests/" - }, - { - "args": [ - "--jobs=1", - "--extra-browser-args=--disable-gpu" - ], - "isolate_name": "telemetry_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "idempotent": false, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 - }, - "test_id_prefix": "ninja://chrome/test:telemetry_unittests/" - }, - { - "args": [ - "--gtest-benchmark-name=views_perftests" - ], - "isolate_name": "views_perftests", - "merge": { - "args": [ - "--smoke-test-mode" - ], - "script": "//tools/perf/process_perf_results.py" - }, - "name": "views_perftests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/views:views_perftests/" - } - ] - }, "Mac10.14 Tests": { "gtest_tests": [ {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 2be2952..4a8b5410 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -263,14 +263,6 @@ 'shards': 25, }, }, - 'Mac10.13 Tests (dbg)': { - 'args': [ - '--debug', - ], - 'swarming': { - 'shards': 25, - }, - }, 'Mac10.15 Tests': { 'swarming': { 'dimension_sets': [ @@ -582,12 +574,6 @@ 'shards': 30, }, }, - 'Mac10.13 Tests (dbg)': { - # https://crbug.com/1152770 - 'swarming': { - 'shards': 40, - }, - }, 'Mac10.15 Tests (dbg)': { # https://crbug.com/1152770 'swarming': { @@ -2064,7 +2050,6 @@ # Only run network service tests on Mac 10.12 for capacity reasons. 'Mac10.11 Tests', 'Mac10.13 Tests', - 'Mac10.13 Tests (dbg)', 'Mac10.15 Tests', 'Mac10.15 Tests (dbg)', 'Mac ASan 64 Tests (1)', @@ -2101,7 +2086,6 @@ # Only run network service tests on Mac 10.12 for capacity reasons. 'Mac10.11 Tests', 'Mac10.13 Tests', - 'Mac10.13 Tests (dbg)', 'Mac10.15 Tests', 'Mac10.15 Tests (dbg)', 'Mac ASan 64 Tests (1)', @@ -2119,7 +2103,6 @@ # Only run network service tests on Mac 10.12 for capacity reasons. 'Mac10.11 Tests', 'Mac10.13 Tests', - 'Mac10.13 Tests (dbg)', 'Mac10.15 Tests', 'Mac10.15 Tests (dbg)', 'Mac ASan 64 Tests (1)', @@ -2136,7 +2119,6 @@ # Only run network service tests on Mac 10.12 for capacity reasons. 'Mac10.11 Tests', 'Mac10.13 Tests', - 'Mac10.13 Tests (dbg)', 'Mac10.15 Tests', 'Mac10.15 Tests (dbg)', 'Mac ASan 64 Tests (1)', @@ -2158,7 +2140,6 @@ # Only run network service tests on Mac 10.12 for capacity reasons. 'Mac10.11 Tests', 'Mac10.13 Tests', - 'Mac10.13 Tests (dbg)', 'Mac10.15 Tests', 'Mac10.15 Tests (dbg)', 'Mac ASan 64 Tests (1)', @@ -2302,11 +2283,6 @@ }, 'performance_test_suite': { 'modifications': { - 'Mac10.13 Tests (dbg)': { - 'args': [ - '--browser=debug', - ], - }, 'Mac10.15 Tests (dbg)': { 'args': [ '--browser=debug', @@ -2685,7 +2661,6 @@ # crbug.com/936540 'Mac10.11 Tests', 'Mac10.13 Tests', - 'Mac10.13 Tests (dbg)', 'Mac10.15 Tests', 'Mac10.15 Tests (dbg)', 'Linux - Future (dbg)', # client.v8.chromium
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index b05026e..4f295c55 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -5150,15 +5150,6 @@ 'isolated_scripts': 'chromium_mac_rel_isolated_scripts', }, }, - 'Mac10.13 Tests (dbg)': { - 'mixins': [ - 'mac_10.15', - ], - 'test_suites': { - 'gtest_tests': 'chromium_mac_gtests', - 'isolated_scripts': 'chromium_dbg_isolated_scripts', - }, - }, 'Mac10.14 Tests': { 'mixins': [ 'mac_10.14',
diff --git a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json index 0eba03f..9091de41 100644 --- a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json +++ b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json
@@ -126,7 +126,9 @@ "canvas_05000_pixels_per_second": { "ci_095": 0.177, "avg": 16.684, - "cpu_wall_time_ratio": 0.268 + "cpu_wall_time_ratio": 0.268, + "experimental": true, + "_comment": "crbug.com/1191220" }, "main_30fps_impl_60fps": { "control": true,
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 78a5e73a..a28935e 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -5008,6 +5008,24 @@ ] } ], + "PdfViewerDocumentProperties": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PdfViewerDocumentProperties" + ] + } + ] + } + ], "PdfViewerPresentationMode": [ { "platforms": [
diff --git a/third_party/androidx/fetch_all_androidx.py b/third_party/androidx/fetch_all_androidx.py index 1ee35cd..e40b907 100755 --- a/third_party/androidx/fetch_all_androidx.py +++ b/third_party/androidx/fetch_all_androidx.py
@@ -63,10 +63,11 @@ # "repository/androidx/library_group/library_name/library_version/pom_or_jar" if len(dir_components) < 6: continue - dependency_module = 'androidx.{}:{}'.format(dir_components[2], - dir_components[3]) + dependency_package = 'androidx.' + '.'.join(dir_components[2:-3]) + dependency_module = '{}:{}'.format(dependency_package, + dir_components[-3]) if dependency_module not in dependency_version_map: - dependency_version_map[dependency_module] = dir_components[4] + dependency_version_map[dependency_module] = dir_components[-2] return dependency_version_map @@ -87,9 +88,10 @@ if not match: return line - version = dependency_version_map.get(match.group(1)) + dependency = match.group(1) + version = dependency_version_map.get(dependency) if not version: - return line + raise Exception(f'Version for {dependency} not found.') return line.replace('{{androidx_dependency_version}}', version)
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index f21afa2..082e637 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -22,6 +22,10 @@ const base::Feature kCOLRV1Fonts{"COLRV1Fonts", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enable CSS Container Queries. Also implies LayoutNGGrid and CSSContainSize1D. +const base::Feature kCSSContainerQueries{"CSSContainerQueries", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kGMSCoreEmoji{"GMSCoreEmoji", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/common/navigation/navigation_policy.cc b/third_party/blink/common/navigation/navigation_policy.cc index 9801fed..791cbd0 100644 --- a/third_party/blink/common/navigation/navigation_policy.cc +++ b/third_party/blink/common/navigation/navigation_policy.cc
@@ -8,6 +8,7 @@ #include "base/metrics/histogram_macros.h" #include "base/system/sys_info.h" #include "services/network/public/cpp/features.h" +#include "third_party/blink/public/common/features.h" namespace blink { @@ -87,4 +88,44 @@ DCHECK(first_type_seen); } +void NavigationDownloadPolicy::ApplyDownloadFramePolicy( + bool is_opener_navigation, + bool has_gesture, + bool can_access_current_origin, + bool has_download_sandbox_flag, + bool is_blocking_downloads_in_sandbox_enabled, + bool from_ad) { + if (!has_gesture) + SetAllowed(NavigationDownloadType::kNoGesture); + + // Disallow downloads on an opener if the requestor is cross origin. + // See crbug.com/632514. + if (is_opener_navigation && !can_access_current_origin) { + SetDisallowed(NavigationDownloadType::kOpenerCrossOrigin); + } + + if (has_download_sandbox_flag) { + if (is_blocking_downloads_in_sandbox_enabled) { + SetDisallowed(NavigationDownloadType::kSandbox); + } else { + SetAllowed(NavigationDownloadType::kSandbox); + } + } + + if (from_ad) { + SetAllowed(NavigationDownloadType::kAdFrame); + if (!has_gesture) { + if (base::FeatureList::IsEnabled( + features::kBlockingDownloadsInAdFrameWithoutUserActivation)) { + SetDisallowed(NavigationDownloadType::kAdFrameNoGesture); + } else { + SetAllowed(NavigationDownloadType::kAdFrameNoGesture); + } + } + } + + blocking_downloads_in_sandbox_enabled = + is_blocking_downloads_in_sandbox_enabled; +} + } // namespace blink
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index fe1a2a6..3567ca84 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -19,6 +19,7 @@ BLINK_COMMON_EXPORT extern const base::Feature kBlockingDownloadsInAdFrameWithoutUserActivation; BLINK_COMMON_EXPORT extern const base::Feature kCOLRV1Fonts; +BLINK_COMMON_EXPORT extern const base::Feature kCSSContainerQueries; BLINK_COMMON_EXPORT extern const base::Feature kGMSCoreEmoji; BLINK_COMMON_EXPORT extern const base::Feature kPaintHolding; BLINK_COMMON_EXPORT extern const base::Feature kPaintHoldingCrossOrigin;
diff --git a/third_party/blink/public/common/navigation/navigation_policy.h b/third_party/blink/public/common/navigation/navigation_policy.h index 548ebbd9..7fd9b4b 100644 --- a/third_party/blink/public/common/navigation/navigation_policy.h +++ b/third_party/blink/public/common/navigation/navigation_policy.h
@@ -75,6 +75,15 @@ // Record the download policy to histograms from |observed_types|. void RecordHistogram() const; + // Possibly set the kOpenerCrossOrigin and kSandboxNoGesture policy in + // |download_policy|. + void ApplyDownloadFramePolicy(bool is_opener_navigation, + bool has_gesture, + bool can_access_current_origin, + bool has_download_sandbox_flag, + bool is_blocking_downloads_in_sandbox_enabled, + bool from_ad); + // An alias of a bitset of navigation types. using NavigationDownloadTypes = std::bitset<static_cast<size_t>(NavigationDownloadType::kMaxValue) + 1>; @@ -87,7 +96,7 @@ // a download, the download should be dropped. NavigationDownloadTypes disallowed_types; - bool blocking_downloads_in_sandbox_enabled = false; + bool blocking_downloads_in_sandbox_enabled; }; } // namespace blink
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index 8b3da68..31c638b 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -870,6 +870,9 @@ // Tells the browser that a child's visual properties have changed. SynchronizeVisualProperties( FrameVisualProperties properties); + + // Requests that the given URL be opened in the specified manner. + OpenURL(blink.mojom.OpenURLParams params); }; // Implemented in Blink, this interface defines frame-specific methods that will
diff --git a/third_party/blink/public/web/web_remote_frame_client.h b/third_party/blink/public/web/web_remote_frame_client.h index e83460b..69df233c 100644 --- a/third_party/blink/public/web/web_remote_frame_client.h +++ b/third_party/blink/public/web/web_remote_frame_client.h
@@ -23,8 +23,6 @@ namespace blink { -class WebURLRequest; - class WebRemoteFrameClient { public: // Specifies the reason for the detachment. @@ -34,21 +32,6 @@ // and release any resources associated with it. virtual void FrameDetached(DetachType) {} - // A remote frame was asked to start a navigation. - virtual void Navigate( - const WebURLRequest& request, - bool should_replace_current_entry, - bool is_opener_navigation, - bool initiator_frame_has_download_sandbox_flag, - bool blocking_downloads_in_sandbox_enabled, - bool initiator_frame_is_ad, - CrossVariantMojoRemote<mojom::BlobURLTokenInterfaceBase> blob_url_token, - const base::Optional<WebImpression>& impression, - const LocalFrameToken* initiator_frame_token, - CrossVariantMojoRemote< - blink::mojom::PolicyContainerHostKeepAliveHandleInterfaceBase> - initiator_policy_container_keep_alive_handle) {} - // Returns an AssociatedInterfaceProvider the frame can use to request // associated interfaces from the browser. virtual AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() = 0;
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 81e4233..7f3b777 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -1750,6 +1750,10 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_capture.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_decoder.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_decoder.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_track.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_track.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_track_list.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_track_list.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_input_device_info.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni index d7f53d4..9ecd3dc 100644 --- a/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -796,6 +796,7 @@ "//third_party/blink/renderer/modules/webcodecs/image_decode_options.idl", "//third_party/blink/renderer/modules/webcodecs/image_decode_result.idl", "//third_party/blink/renderer/modules/webcodecs/image_track.idl", + "//third_party/blink/renderer/modules/webcodecs/image_track_list.idl", "//third_party/blink/renderer/modules/webcodecs/plane.idl", "//third_party/blink/renderer/modules/webcodecs/plane_init.idl", "//third_party/blink/renderer/modules/webcodecs/video_color_space.idl",
diff --git a/third_party/blink/renderer/core/document_transition/document_transition.cc b/third_party/blink/renderer/core/document_transition/document_transition.cc index 199e13ce..e26900a7 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition.cc +++ b/third_party/blink/renderer/core/document_transition/document_transition.cc
@@ -19,9 +19,6 @@ namespace blink { namespace { -constexpr base::TimeDelta kDefaultDuration = - base::TimeDelta::FromMilliseconds(300); - DocumentTransition::Request::Effect ParseEffect(const String& input) { using MapType = HashMap<String, DocumentTransition::Request::Effect>; DEFINE_STATIC_LOCAL( @@ -44,12 +41,6 @@ : DocumentTransition::Request::Effect::kNone; } -base::TimeDelta ParseDuration(const DocumentTransitionPrepareOptions* options) { - return options->hasDuration() - ? base::TimeDelta::FromMilliseconds(options->duration()) - : kDefaultDuration; -} - DocumentTransition::Request::Effect ParseRootTransition( const DocumentTransitionPrepareOptions* options) { return options->hasRootTransition() @@ -133,7 +124,6 @@ } // We're going to be creating a new transition, parse the options. - auto duration = ParseDuration(options); auto effect = ParseRootTransition(options); if (options->hasSharedElements()) SetActiveSharedElements(options->sharedElements()); @@ -144,7 +134,7 @@ state_ = State::kPreparing; pending_request_ = Request::CreatePrepare( - effect, duration, document_tag_, prepare_shared_element_count_, + effect, document_tag_, prepare_shared_element_count_, ConvertToBaseOnceCallback(CrossThreadBindOnce( &DocumentTransition::NotifyPrepareFinished, WrapCrossThreadWeakPersistent(this), last_prepare_sequence_id_)));
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_prepare_options.idl b/third_party/blink/renderer/core/document_transition/document_transition_prepare_options.idl index 5bb8910..cb52fd68c6 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition_prepare_options.idl +++ b/third_party/blink/renderer/core/document_transition/document_transition_prepare_options.idl
@@ -19,6 +19,5 @@ dictionary DocumentTransitionPrepareOptions { RootTransitionType rootTransition; - DOMTimeStamp duration; sequence<Element?> sharedElements; };
diff --git a/third_party/blink/renderer/core/document_transition/document_transition_test.cc b/third_party/blink/renderer/core/document_transition/document_transition_test.cc index 455a0bc8..f81c2c6 100644 --- a/third_party/blink/renderer/core/document_transition/document_transition_test.cc +++ b/third_party/blink/renderer/core/document_transition/document_transition_test.cc
@@ -208,35 +208,6 @@ EXPECT_EQ(directive.effect(), DocumentTransition::Request::Effect::kExplode); } -TEST_P(DocumentTransitionTest, DurationParsing) { - // Test default init. - auto* transition = - DocumentTransitionSupplement::documentTransition(GetDocument()); - - V8TestingScope v8_scope; - ScriptState* script_state = v8_scope.GetScriptState(); - ExceptionState& exception_state = v8_scope.GetExceptionState(); - DocumentTransitionPrepareOptions default_options; - transition->prepare(script_state, &default_options, exception_state); - - auto request = transition->TakePendingRequest(); - ASSERT_TRUE(request); - - auto directive = request->ConstructDirective({}); - EXPECT_EQ(directive.duration(), base::TimeDelta::FromMilliseconds(300)); - - // Test set duration parsing. - DocumentTransitionPrepareOptions explode_options; - explode_options.setDuration(123); - transition->prepare(script_state, &explode_options, exception_state); - - request = transition->TakePendingRequest(); - ASSERT_TRUE(request); - - directive = request->ConstructDirective({}); - EXPECT_EQ(directive.duration(), base::TimeDelta::FromMilliseconds(123)); -} - TEST_P(DocumentTransitionTest, PrepareSharedElementsWantToBeComposited) { SetHtmlInnerHTML(R"HTML( <style>
diff --git a/third_party/blink/renderer/core/frame/DEPS b/third_party/blink/renderer/core/frame/DEPS index 2ba716e..0f676c48 100644 --- a/third_party/blink/renderer/core/frame/DEPS +++ b/third_party/blink/renderer/core/frame/DEPS
@@ -38,6 +38,9 @@ "remote_frame\.h": [ "+components/viz/common/surfaces/parent_local_surface_id_allocator.h", ], + "remote_frame\.cc": [ + "+ui/base/window_open_disposition.h", + ], "remote_frame_view\.cc": [ "+cc/base/math_util.h", "+components/paint_preview/common/paint_preview_tracker.h",
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc index 5f2d5ac..439af01 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -8,11 +8,17 @@ #include "cc/layers/surface_layer.h" #include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/common/navigation/navigation_policy.h" +#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h" #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h" #include "third_party/blink/public/mojom/frame/intrinsic_sizing_info.mojom-blink.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom-blink.h" #include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h" +#include "third_party/blink/public/platform/impression_conversions.h" #include "third_party/blink/public/platform/interface_registry.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/url_conversion.h" +#include "third_party/blink/public/platform/web_url_request_util.h" #include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_view.h" #include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h" @@ -46,6 +52,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/core/timing/dom_window_performance.h" +#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h" @@ -55,6 +62,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h" +#include "ui/base/window_open_disposition.h" namespace blink { @@ -254,15 +262,50 @@ // TODO(https://crbug.com/1173409 and https://crbug.com/1059959): Check that // we always have valid |initiator_frame_token| and // |initiator_policy_container_keep_alive_handle|. + ResourceRequest& request = frame_request.GetResourceRequest(); + DCHECK(request.RequestorOrigin().get()); - Client()->Navigate(frame_request.GetResourceRequest(), - frame_load_type == WebFrameLoadType::kReplaceCurrentItem, - is_opener_navigation, - initiator_frame_has_download_sandbox_flag, - initiator_frame_is_ad, frame_request.GetBlobURLToken(), - frame_request.Impression(), - base::OptionalOrNullptr(initiator_frame_token), - std::move(initiator_policy_container_keep_alive_handle)); + auto params = mojom::blink::OpenURLParams::New(); + params->url = url; + params->initiator_origin = request.RequestorOrigin(); + params->post_body = + blink::GetRequestBodyForWebURLRequest(WrappedResourceRequest(request)); + DCHECK_EQ(!!params->post_body, request.HttpMethod().Utf8() == "POST"); + params->extra_headers = + blink::GetWebURLRequestHeadersAsString(WrappedResourceRequest(request)); + params->referrer = mojom::blink::Referrer::New( + KURL(NullURL(), request.ReferrerString()), request.GetReferrerPolicy()); + params->disposition = ui::mojom::blink::WindowOpenDisposition::CURRENT_TAB; + params->should_replace_current_entry = + frame_load_type == WebFrameLoadType::kReplaceCurrentItem; + params->user_gesture = request.HasUserGesture(); + params->triggering_event_info = mojom::blink::TriggeringEventInfo::kUnknown; + params->blob_url_token = frame_request.GetBlobURLToken(); + params->href_translate = + String(frame_request.HrefTranslate().Latin1().c_str()); + params->initiator_policy_container_keep_alive_handle = + std::move(initiator_policy_container_keep_alive_handle); + params->initiator_frame_token = + base::OptionalFromPtr(base::OptionalOrNullptr(initiator_frame_token)); + + if (frame_request.Impression()) { + params->impression = + blink::ConvertWebImpressionToImpression(*frame_request.Impression()); + } + + // Note: For the AdFrame/Sandbox download policy here it only covers the case + // where the navigation initiator frame is ad. The download_policy may be + // further augmented in RenderFrameProxyHost::OnOpenURL if the navigating + // frame is ad or sandboxed. + params->download_policy.ApplyDownloadFramePolicy( + is_opener_navigation, request.HasUserGesture(), + request.RequestorOrigin()->CanAccess( + GetSecurityContext()->GetSecurityOrigin()), + initiator_frame_has_download_sandbox_flag, + RuntimeEnabledFeatures::BlockingDownloadsInSandboxEnabled(), + initiator_frame_is_ad); + + GetRemoteFrameHostRemote().OpenURL(std::move(params)); } bool RemoteFrame::DetachImpl(FrameDetachType type) {
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client.h b/third_party/blink/renderer/core/frame/remote_frame_client.h index e208882..9881e35 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client.h +++ b/third_party/blink/renderer/core/frame/remote_frame_client.h
@@ -19,23 +19,11 @@ namespace blink { class AssociatedInterfaceProvider; -class ResourceRequest; class RemoteFrameClient : public FrameClient { public: ~RemoteFrameClient() override = default; - virtual void Navigate( - const ResourceRequest&, - bool should_replace_current_entry, - bool is_opener_navigation, - bool initiator_frame_has_download_sandbox_flag, - bool initiator_frame_is_ad, - mojo::PendingRemote<mojom::blink::BlobURLToken>, - const base::Optional<WebImpression>& impression, - const LocalFrameToken* initiator_frame_token, - mojo::PendingRemote<mojom::blink::PolicyContainerHostKeepAliveHandle> - initiator_policy_container_keep_alive_handle) = 0; unsigned BackForwardLength() override = 0; virtual AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() = 0;
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc index dfa6307..9a78fa1 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc +++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
@@ -64,29 +64,6 @@ web_frame_->SetCoreFrame(nullptr); } -void RemoteFrameClientImpl::Navigate( - const ResourceRequest& request, - bool should_replace_current_entry, - bool is_opener_navigation, - bool initiator_frame_has_download_sandbox_flag, - bool initiator_frame_is_ad, - mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token, - const base::Optional<WebImpression>& impression, - const LocalFrameToken* initiator_frame_token, - mojo::PendingRemote<mojom::blink::PolicyContainerHostKeepAliveHandle> - initiator_policy_container_keep_alive_handle) { - bool blocking_downloads_in_sandbox_enabled = - RuntimeEnabledFeatures::BlockingDownloadsInSandboxEnabled(); - if (web_frame_->Client()) { - web_frame_->Client()->Navigate( - WrappedResourceRequest(request), should_replace_current_entry, - is_opener_navigation, initiator_frame_has_download_sandbox_flag, - blocking_downloads_in_sandbox_enabled, initiator_frame_is_ad, - std::move(blob_url_token), impression, initiator_frame_token, - std::move(initiator_policy_container_keep_alive_handle)); - } -} - unsigned RemoteFrameClientImpl::BackForwardLength() { // TODO(creis,japhet): This method should return the real value for the // session history length. For now, return static value for the initial
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h index 7866626..1d2522c 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h +++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
@@ -21,18 +21,6 @@ bool InShadowTree() const override; void Detached(FrameDetachType) override; - // RemoteFrameClient overrides: - void Navigate( - const ResourceRequest&, - bool should_replace_current_entry, - bool is_opener_navigation, - bool prevent_sandboxed_download, - bool initiator_frame_is_ad, - mojo::PendingRemote<mojom::blink::BlobURLToken>, - const base::Optional<WebImpression>& impression, - const LocalFrameToken* initiator_frame_token, - mojo::PendingRemote<mojom::blink::PolicyContainerHostKeepAliveHandle> - initiator_policy_container_keep_alive_handle) override; unsigned BackForwardLength() override; AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override;
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index 650ff87..be631bc 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -66,6 +66,7 @@ #include "third_party/blink/public/mojom/blob/data_element.mojom-blink.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h" +#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h" #include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom-blink.h" #include "third_party/blink/public/mojom/frame/viewport_intersection_state.mojom-blink.h" #include "third_party/blink/public/mojom/page_state/page_state.mojom-blink.h" @@ -9697,37 +9698,71 @@ Reset(); } -class RemoteNavigationClient - : public frame_test_helpers::TestWebRemoteFrameClient { +class RemoteFrameHostInterceptor : public mojom::blink::RemoteFrameHost { public: - RemoteNavigationClient() = default; - ~RemoteNavigationClient() override = default; + explicit RemoteFrameHostInterceptor( + blink::AssociatedInterfaceProvider* provider) { + provider->OverrideBinderForTesting( + mojom::blink::RemoteFrameHost::Name_, + base::BindRepeating( + &RemoteFrameHostInterceptor::BindRemoteFrameHostReceiver, + base::Unretained(this))); + } + ~RemoteFrameHostInterceptor() override = default; - // frame_test_helpers::TestWebRemoteFrameClient: - void Navigate( - const WebURLRequest& request, - bool should_replace_current_entry, - bool is_opener_navigation, - bool initiator_frame_has_download_sandbox_flag, - bool blocking_downloads_in_sandbox_enabled, - bool initiator_frame_is_ad, - CrossVariantMojoRemote<mojom::blink::BlobURLTokenInterfaceBase>, - const base::Optional<WebImpression>& impression, - const blink::LocalFrameToken* initiator_frame_token, - blink::CrossVariantMojoRemote< - blink::mojom::PolicyContainerHostKeepAliveHandleInterfaceBase> - initiator_policy_container_keep_alive_handle) override { - last_request_.CopyFrom(request); + void BindRemoteFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle) { + receiver_.Bind( + mojo::PendingAssociatedReceiver<mojom::blink::RemoteFrameHost>( + std::move(handle))); } - const WebURLRequest& LastRequest() const { return last_request_; } + void SetInheritedEffectiveTouchAction(cc::TouchAction touch_action) override { + } + void UpdateRenderThrottlingStatus(bool is_throttled, + bool subtree_throttled, + bool display_locked) override {} + void VisibilityChanged(mojom::blink::FrameVisibility visibility) override {} + void DidFocusFrame() override {} + void CheckCompleted() override {} + void CapturePaintPreviewOfCrossProcessSubframe( + const gfx::Rect& clip_rect, + const base::UnguessableToken& guid) override {} + void SetIsInert(bool inert) override {} + void DidChangeOpener( + const base::Optional<LocalFrameToken>& opener_frame) override {} + void AdvanceFocus(blink::mojom::FocusType focus_type, + const LocalFrameToken& source_frame_token) override {} + void RouteMessageEvent( + const base::Optional<LocalFrameToken>& source_frame_token, + const String& source_origin, + const String& target_origin, + BlinkTransferableMessage message) override {} + void PrintCrossProcessSubframe(const gfx::Rect& rect, + int document_cookie) override {} + void Detach() override {} + void UpdateViewportIntersection( + blink::mojom::blink::ViewportIntersectionStatePtr intersection_state, + const base::Optional<FrameVisualProperties>& visual_properties) override { + } + + void SynchronizeVisualProperties( + const blink::FrameVisualProperties& properties) override {} + + void OpenURL(mojom::blink::OpenURLParamsPtr params) override { + intercepted_params_ = std::move(params); + } + + const mojom::blink::OpenURLParamsPtr& GetInterceptedParams() { + return intercepted_params_; + } private: - WebURLRequest last_request_; + mojo::AssociatedReceiver<mojom::blink::RemoteFrameHost> receiver_{this}; + mojom::blink::OpenURLParamsPtr intercepted_params_; }; TEST_F(WebFrameSwapTest, NavigateRemoteFrameViaLocation) { - RemoteNavigationClient client; + frame_test_helpers::TestWebRemoteFrameClient client; WebRemoteFrame* remote_frame = frame_test_helpers::CreateRemote(&client); WebFrame* target_frame = MainFrame()->FirstChild(); ASSERT_TRUE(target_frame); @@ -9735,13 +9770,17 @@ ASSERT_TRUE(MainFrame()->FirstChild()); ASSERT_EQ(MainFrame()->FirstChild(), remote_frame); + RemoteFrameHostInterceptor interceptor( + client.GetRemoteAssociatedInterfaces()); remote_frame->SetReplicatedOrigin( WebSecurityOrigin::CreateFromString("http://127.0.0.1"), false); MainFrame()->ExecuteScript( WebScriptSource("document.getElementsByTagName('iframe')[0]." "contentWindow.location = 'data:text/html,hi'")); - ASSERT_FALSE(client.LastRequest().IsNull()); - EXPECT_EQ(WebURL(ToKURL("data:text/html,hi")), client.LastRequest().Url()); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(interceptor.GetInterceptedParams()); + EXPECT_EQ(ToKURL("data:text/html,hi"), + KURL(interceptor.GetInterceptedParams()->url)); // Manually reset to break WebViewHelper's dependency on the stack allocated // TestWebFrameClient. @@ -9749,7 +9788,7 @@ } TEST_F(WebFrameSwapTest, WindowOpenOnRemoteFrame) { - RemoteNavigationClient remote_client; + frame_test_helpers::TestWebRemoteFrameClient remote_client; WebRemoteFrame* remote_frame = frame_test_helpers::CreateRemote(&remote_client); MainFrame()->FirstChild()->Swap(remote_frame); @@ -9760,6 +9799,8 @@ LocalDOMWindow* main_window = To<WebLocalFrameImpl>(MainFrame())->GetFrame()->DomWindow(); + RemoteFrameHostInterceptor interceptor( + remote_client.GetRemoteAssociatedInterfaces()); String destination = "data:text/html:destination"; NonThrowableExceptionState exception_state; ScriptState* script_state = @@ -9769,14 +9810,17 @@ script_state->GetContext()); main_window->open(script_state->GetIsolate(), destination, "frame1", "", exception_state); - ASSERT_FALSE(remote_client.LastRequest().IsNull()); - EXPECT_EQ(remote_client.LastRequest().Url(), WebURL(KURL(destination))); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(interceptor.GetInterceptedParams()); + EXPECT_EQ(KURL(interceptor.GetInterceptedParams()->url), KURL(destination)); // Pointing a named frame to an empty URL should just return a reference to // the frame's window without navigating it. DOMWindow* result = main_window->open(script_state->GetIsolate(), "", "frame1", "", exception_state); - EXPECT_EQ(remote_client.LastRequest().Url(), WebURL(KURL(destination))); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(interceptor.GetInterceptedParams()); + EXPECT_EQ(KURL(interceptor.GetInterceptedParams()->url), KURL(destination)); EXPECT_EQ(result, WebFrame::ToCoreFrame(*remote_frame)->DomWindow()); Reset();
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc index 56389e3..43b50d8 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
@@ -193,7 +193,9 @@ if (old_style) { bool borders_changed = !old_style->BorderVisuallyEqual(StyleRef()) || - old_style->GetWritingMode() != StyleRef().GetWritingMode() || + old_style->GetWritingDirection() != StyleRef().GetWritingDirection() || + old_style->IsFixedTableLayout() != StyleRef().IsFixedTableLayout() || + old_style->EmptyCells() != StyleRef().EmptyCells() || (diff.TextDecorationOrColorChanged() && StyleRef().HasBorderColorReferencingCurrentColor()); bool collapse_changed =
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc index 944974e..7b8699e 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
@@ -113,8 +113,8 @@ NOT_DESTROYED(); if (LayoutNGTable* table = Table()) { if ((old_style && !old_style->BorderVisuallyEqual(StyleRef())) || - (old_style && - old_style->GetWritingMode() != StyleRef().GetWritingMode()) || + (old_style && old_style->GetWritingDirection() != + StyleRef().GetWritingDirection()) || (diff.TextDecorationOrColorChanged() && StyleRef().HasBorderColorReferencingCurrentColor())) { table->GridBordersChanged();
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc index 93f96140..f1f1452 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc
@@ -98,8 +98,8 @@ NOT_DESTROYED(); if (LayoutNGTable* table = Table()) { if ((old_style && !old_style->BorderVisuallyEqual(StyleRef())) || - (old_style && - old_style->GetWritingMode() != StyleRef().GetWritingMode()) || + (old_style && old_style->GetWritingDirection() != + StyleRef().GetWritingDirection()) || (diff.TextDecorationOrColorChanged() && StyleRef().HasBorderColorReferencingCurrentColor())) { table->GridBordersChanged();
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc index 8c01d38..146316a 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc
@@ -94,8 +94,8 @@ NOT_DESTROYED(); if (LayoutNGTable* table = Table()) { if ((old_style && !old_style->BorderVisuallyEqual(StyleRef())) || - (old_style && - old_style->GetWritingMode() != StyleRef().GetWritingMode()) || + (old_style && old_style->GetWritingDirection() != + StyleRef().GetWritingDirection()) || (diff.TextDecorationOrColorChanged() && StyleRef().HasBorderColorReferencingCurrentColor())) { table->GridBordersChanged();
diff --git a/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc b/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc index a4d2140..0e88848 100644 --- a/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc +++ b/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc
@@ -58,6 +58,8 @@ void FakeRemoteFrameHost::SynchronizeVisualProperties( const blink::FrameVisualProperties& properties) {} +void FakeRemoteFrameHost::OpenURL(mojom::blink::OpenURLParamsPtr params) {} + void FakeRemoteFrameHost::BindFrameHostReceiver( mojo::ScopedInterfaceEndpointHandle handle) { receiver_.Bind(mojo::PendingAssociatedReceiver<mojom::blink::RemoteFrameHost>(
diff --git a/third_party/blink/renderer/core/testing/fake_remote_frame_host.h b/third_party/blink/renderer/core/testing/fake_remote_frame_host.h index 91a1d71..6523497 100644 --- a/third_party/blink/renderer/core/testing/fake_remote_frame_host.h +++ b/third_party/blink/renderer/core/testing/fake_remote_frame_host.h
@@ -55,6 +55,8 @@ void SynchronizeVisualProperties( const blink::FrameVisualProperties& properties) override; + void OpenURL(mojom::blink::OpenURLParamsPtr params) override; + private: void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/third_party/blink/renderer/modules/webcodecs/BUILD.gn index f03bd1d..40197e6 100644 --- a/third_party/blink/renderer/modules/webcodecs/BUILD.gn +++ b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
@@ -40,6 +40,10 @@ "hardware_preference.h", "image_decoder_external.cc", "image_decoder_external.h", + "image_track.cc", + "image_track.h", + "image_track_list.cc", + "image_track_list.h", "plane.cc", "plane.h", "video_decoder.cc",
diff --git a/third_party/blink/renderer/modules/webcodecs/idls.gni b/third_party/blink/renderer/modules/webcodecs/idls.gni index 75a9552..e76f5df 100644 --- a/third_party/blink/renderer/modules/webcodecs/idls.gni +++ b/third_party/blink/renderer/modules/webcodecs/idls.gni
@@ -9,6 +9,8 @@ "encoded_audio_chunk.idl", "encoded_video_chunk.idl", "image_decoder.idl", + "image_track.idl", + "image_track_list.idl", "plane.idl", "video_decoder.idl", "video_encoder.idl", @@ -38,7 +40,6 @@ "image_decode_options.idl", "image_decode_result.idl", "image_decoder_init.idl", - "image_track.idl", "plane_init.idl", "video_color_space.idl", "video_decoder_config.idl",
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder.idl b/third_party/blink/renderer/modules/webcodecs/image_decoder.idl index 8b5e173..b893b12 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder.idl +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder.idl
@@ -29,16 +29,6 @@ // metadata at the time of construction. Promise<void> decodeMetadata(); - // Selects another track of the image. Destructively recreates the underlying - // decoder. Identical track selections will be ignored. Invalid track - // selections will raise an exception. Clears the |preferAnimation| flag if - // one was provided during construction. - // - // Changing tracks will resolve all outstanding decode requests as rejected - // and reset any partially decoded frame state. Outstanding ImageFrames and - // metadata decode promises will remain valid. - [RaisesException] void selectTrack(unsigned long trackId); - // Aborts all pending metadata and decode promises. void reset(); @@ -48,29 +38,18 @@ // Not recoverable: make a new ImageDecoder if needed. void close(); - // The number of frames in the image. - // - // When decoding a ReadableStream the value will be 0 until enough data to - // decode metadata has been received. If the format has no fixed count, the - // value will increase as frames are received by the decoder. - readonly attribute unsigned long frameCount; - // The mime type for the decoded image. This reflects the value provided // during construction. readonly attribute DOMString type; - // The image's preferred repetition count. - // - // When decoding a ReadableStream the value will be 0 until enough data to - // decode metadata has been received. - readonly attribute unsigned long repetitionCount; - - // True if all available frames have been received by the decoder. + // True if all available data has been received by the decoder. Always true + // when an ArrayBuffer is provided at construction. False for ReadableStream + // usage readonly attribute boolean complete; // List of tracks available in this image. // // When decoding a ReadableStream the array will be empty until enough data to // decode metadata has been received. - readonly attribute FrozenArray<ImageTrack> tracks; + [SameObject] readonly attribute ImageTrackList tracks; };
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc index d55129d..d4295e6b 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
@@ -12,15 +12,14 @@ #include "media/base/video_util.h" #include "third_party/blink/public/common/mime_util/mime_util.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_image_decode_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_image_decode_result.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_image_decoder_init.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_image_track.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h" -#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h" +#include "third_party/blink/renderer/modules/webcodecs/image_track.h" +#include "third_party/blink/renderer/modules/webcodecs/image_track_list.h" #include "third_party/blink/renderer/modules/webcodecs/video_frame.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -39,6 +38,34 @@ IsSupportedImageMimeType(type.Ascii()); } +ImageDecoder::AnimationOption AnimationOptionFromIsAnimated(bool is_animated) { + return is_animated ? ImageDecoder::AnimationOption::kPreferAnimation + : ImageDecoder::AnimationOption::kPreferStillImage; +} + +DOMException* CreateUnsupportedImageTypeException(String type) { + return MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotSupportedError, + String::Format("The provided image type (%s) is not supported", + type.Ascii().c_str())); +} + +DOMException* CreateClosedException() { + return MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, "The decoder has been closed."); +} + +DOMException* CreateNoSelectedTracksException() { + return MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, "No selected track."); +} + +DOMException* CreateDecodeFailure(uint32_t index) { + return MakeGarbageCollected<DOMException>( + DOMExceptionCode::kEncodingError, + String::Format("Failed to decode frame at index %d", index)); +} + } // namespace // static @@ -78,7 +105,8 @@ const ImageDecoderInit* init, ExceptionState& exception_state) : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)), - script_state_(script_state) { + script_state_(script_state), + tracks_(MakeGarbageCollected<ImageTrackList>(this)) { UseCounter::Count(ExecutionContext::From(script_state), WebFeature::kWebCodecs); @@ -98,8 +126,10 @@ if (!IsTypeSupportedInternal(mime_type_)) return; - if (init->hasPreferAnimation()) + if (init->hasPreferAnimation()) { prefer_animation_ = init->preferAnimation(); + animation_option_ = AnimationOptionFromIsAnimated(*prefer_animation_); + } if (init->data().IsReadableStream()) { if (init->data().GetAsReadableStream()->IsLocked() || @@ -177,7 +207,9 @@ } if (!decoder_) { - resolver->Reject(CreateUnsupportedImageTypeException()); + resolver->Reject(IsTypeSupportedInternal(mime_type_) + ? CreateNoSelectedTracksException() + : CreateUnsupportedImageTypeException(mime_type_)); return promise; } @@ -200,7 +232,14 @@ } if (!decoder_) { - resolver->Reject(CreateUnsupportedImageTypeException()); + // We may have no selected tracks at this point. + if (IsTypeSupportedInternal(mime_type_)) { + DCHECK(pending_metadata_decodes_.IsEmpty()); + resolver->Resolve(); + return promise; + } + + resolver->Reject(CreateUnsupportedImageTypeException(mime_type_)); return promise; } @@ -209,64 +248,37 @@ return promise; } -void ImageDecoderExternal::selectTrack(uint32_t track_id, - ExceptionState& exception_state) { - if (closed_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - "The decoder has been closed."); - return; - } +void ImageDecoderExternal::UpdateSelectedTrack() { + DCHECK(!closed_); - if (track_id >= tracks_.size()) { - exception_state.ThrowRangeError( - ExceptionMessages::IndexOutsideRange<uint32_t>( - "track index", track_id, 0, ExceptionMessages::kInclusiveBound, - tracks_.size(), ExceptionMessages::kExclusiveBound)); - return; - } - - // Returning early allows us to avoid churn from unnecessarily destructing the - // underlying ImageDecoder interface. - if (tracks_.size() == 1 || selected_track_id_ == track_id) - return; - - // Promise resolution may be reentrant, so continuously abort promises. - while (!pending_decodes_.IsEmpty()) { - AbortPendingDecodes(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kAbortError, "Aborted by track change")); - } + reset(MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError, + "Aborted by track change")); // TODO(crbug.com/1073995): We eventually need a formal track selection // mechanism. For now we can only select between the still and animated images // and must destruct the decoder for changes. decoder_.reset(); - selected_track_id_ = track_id; - prefer_animation_ = tracks_[track_id]->animated(); + if (!tracks_->selectedTrack()) + return; + + animation_option_ = AnimationOptionFromIsAnimated( + tracks_->selectedTrack().value()->animated()); CreateImageDecoder(); MaybeUpdateMetadata(); MaybeSatisfyPendingDecodes(); } -uint32_t ImageDecoderExternal::frameCount() const { - return frame_count_; -} - String ImageDecoderExternal::type() const { return mime_type_; } -uint32_t ImageDecoderExternal::repetitionCount() const { - return repetition_count_; -} - bool ImageDecoderExternal::complete() const { return data_complete_; } -const ImageDecoderExternal::ImageTrackList ImageDecoderExternal::tracks() - const { - return tracks_; +ImageTrackList& ImageDecoderExternal::tracks() const { + return *tracks_; } void ImageDecoderExternal::reset(DOMException* exception) { @@ -291,8 +303,7 @@ consumer_->Cancel(); consumer_ = nullptr; decoder_.reset(); - tracks_.clear(); - frame_count_ = repetition_count_ = 0; + tracks_->Disconnect(); mime_type_ = ""; stream_buffer_ = nullptr; segment_reader_ = nullptr; @@ -363,7 +374,8 @@ DCHECK(IsTypeSupportedInternal(mime_type_)); decoder_ = ImageDecoder::CreateByMimeType( mime_type_, segment_reader_, data_complete_, alpha_option_, - ImageDecoder::kHighBitDepthToHalfFloat, color_behavior_, desired_size_); + ImageDecoder::kHighBitDepthToHalfFloat, color_behavior_, desired_size_, + animation_option_); // CreateByImageType() can't fail if we use a supported image type. Which we // DCHECK above via isTypeSupported(). @@ -373,17 +385,27 @@ void ImageDecoderExternal::MaybeSatisfyPendingDecodes() { DCHECK(!closed_); DCHECK(decoder_); + for (auto& request : pending_decodes_) { + if (decoder_->Failed()) { + request->exception = CreateDecodeFailure(request->frame_index); + continue; + } if (!data_complete_) { // We can't fulfill this promise at this time. - if (request->frame_index >= frame_count_) + if (tracks_->IsEmpty() || + request->frame_index >= + tracks_->selectedTrack().value()->frameCount()) { continue; - } else if (request->frame_index >= frame_count_) { + } + } else if (request->frame_index >= + tracks_->selectedTrack().value()->frameCount()) { request->exception = MakeGarbageCollected<DOMException>( DOMExceptionCode::kIndexSizeError, ExceptionMessages::IndexOutsideRange<uint32_t>( "frame index", request->frame_index, 0, - ExceptionMessages::kInclusiveBound, frame_count_, + ExceptionMessages::kInclusiveBound, + tracks_->selectedTrack().value()->frameCount(), ExceptionMessages::kExclusiveBound)); continue; } @@ -397,10 +419,7 @@ auto* image = decoder_->DecodeFrameBufferAtIndex(request->frame_index); if (decoder_->Failed() || !image) { - request->exception = MakeGarbageCollected<DOMException>( - DOMExceptionCode::kEncodingError, - String::Format("Failed to decode frame at index %d", - request->frame_index)); + request->exception = CreateDecodeFailure(request->frame_index); continue; } @@ -497,8 +516,12 @@ return; DCHECK(decoder_->Failed() || decoder_->IsDecodedSizeAvailable()); - for (auto& resolver : pending_metadata_decodes_) - resolver->Resolve(); + for (auto& resolver : pending_metadata_decodes_) { + if (decoder_->Failed()) + resolver->Reject(); + else + resolver->Resolve(); + } pending_metadata_decodes_.clear(); } @@ -517,45 +540,47 @@ return; } - const size_t decoded_frame_count = decoder_->FrameCount(); + uint32_t frame_count = static_cast<uint32_t>(decoder_->FrameCount()); if (decoder_->Failed()) { MaybeSatisfyPendingMetadataDecodes(); return; } - frame_count_ = static_cast<uint32_t>(decoded_frame_count); + int repetition_count = decoder_->RepetitionCount(); + if (decoder_->Failed()) { + MaybeSatisfyPendingMetadataDecodes(); + return; + } - // The internal value has some magic negative numbers; for external purposes - // we want to only surface positive repetition counts. The rest is up to the - // client. - const int decoded_repetition_count = decoder_->RepetitionCount(); - if (decoded_repetition_count > 0) - repetition_count_ = decoded_repetition_count; - - // TODO(crbug.com/1073995): None of the underlying ImageDecoders actually - // expose tracks yet. So for now just assume a still and animated track for - // images which declare to be multi-image and have animations. - if (tracks_.IsEmpty()) { - auto* track = ImageTrackExternal::Create(); - track->setId(0); - tracks_.push_back(track); + if (tracks_->IsEmpty()) { + // TODO(crbug.com/1073995): None of the underlying ImageDecoders actually + // expose tracks yet. So for now just assume a still and animated track for + // images which declare to be multi-image and have animations. if (decoder_->ImageHasBothStillAndAnimatedSubImages()) { - track->setAnimated(false); + int selected_track_id = 1; // Currently animation is always default. + if (prefer_animation_.has_value()) { + selected_track_id = prefer_animation_.value() ? 1 : 0; + + // Sadly there's currently no way to get the frame count information for + // unselected tracks, so for now just leave frame count as unknown but + // force repetition count to be animated. + if (!prefer_animation_.value()) { + frame_count = 0; + repetition_count = kAnimationLoopOnce; + } + } // All multi-track images have a still image track. Even if it's just the // first frame of the animation. - track = ImageTrackExternal::Create(); - track->setId(1); - track->setAnimated(true); - tracks_.push_back(track); - - if (prefer_animation_.has_value()) - selected_track_id_ = prefer_animation_.value() ? 1 : 0; + tracks_->AddTrack(1, kAnimationNone, selected_track_id == 0); + tracks_->AddTrack(frame_count, repetition_count, selected_track_id == 1); } else { - track->setAnimated(frame_count_ > 1); - selected_track_id_ = 0; + tracks_->AddTrack(frame_count, repetition_count, true); } + } else { + tracks_->selectedTrack().value()->UpdateTrack(frame_count, + repetition_count); } MaybeSatisfyPendingMetadataDecodes(); @@ -579,20 +604,6 @@ return true; } -DOMException* ImageDecoderExternal::CreateUnsupportedImageTypeException() - const { - DCHECK(!decoder_); - return MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError, - String::Format("The provided image type (%s) is not supported", - mime_type_.Ascii().c_str())); -} - -DOMException* ImageDecoderExternal::CreateClosedException() const { - return MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, "The decoder has been closed."); -} - void ImageDecoderExternal::AbortPendingDecodes(DOMException* exception) { // Swap to a local variable since promise handling may be reentrant. HeapVector<Member<DecodeRequest>> local_pending_decodes;
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h index 2349ae4f..61c946c 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
@@ -24,7 +24,7 @@ class ImageDecodeOptions; class ImageDecoderInit; class ImageDecodeResult; -class ImageTrackExternal; +class ImageTrackList; class ReadableStreamBytesConsumer; class ScriptPromiseResolver; class SegmentReader; @@ -46,19 +46,14 @@ static ScriptPromise isTypeSupported(ScriptState*, String type); - using ImageTrackList = HeapVector<Member<ImageTrackExternal>>; - // image_decoder.idl implementation. ScriptPromise decode(const ImageDecodeOptions* options = nullptr); ScriptPromise decodeMetadata(); - void selectTrack(uint32_t track_id, ExceptionState&); - uint32_t frameCount() const; - String type() const; - uint32_t repetitionCount() const; - bool complete() const; - const ImageTrackList tracks() const; void reset(DOMException* exception = nullptr); void close(); + String type() const; + bool complete() const; + ImageTrackList& tracks() const; // BytesConsumer::Client implementation. void OnStateChange() override; @@ -73,6 +68,9 @@ // ScriptWrappable override. bool HasPendingActivity() const override; + // Called by ImageTrack to change the current track. + void UpdateSelectedTrack(); + private: void CreateImageDecoder(); @@ -84,10 +82,6 @@ // ArrayBufferView that has since been neutered. bool HasValidEncodedData() const; - // Helpers for creating common exceptions for rejecting promises. - DOMException* CreateUnsupportedImageTypeException() const; - DOMException* CreateClosedException() const; - void AbortPendingDecodes(DOMException* exception); Member<ScriptState> script_state_; @@ -105,20 +99,20 @@ ColorBehavior color_behavior_ = ColorBehavior::Tag(); SkISize desired_size_; - // Copy of |preferAnimation| from |init_data_|. Will be modified based on - // calls to selectTrack(). + // Copy of |preferAnimation| from |init_data_|. base::Optional<bool> prefer_animation_; + // Currently configured AnimationOption for |decoder_|. + ImageDecoder::AnimationOption animation_option_ = + ImageDecoder::AnimationOption::kUnspecified; + bool data_complete_ = false; bool closed_ = false; std::unique_ptr<ImageDecoder> decoder_; String mime_type_; - uint32_t frame_count_ = 0u; - uint32_t repetition_count_ = 0u; - base::Optional<uint32_t> selected_track_id_; - ImageTrackList tracks_; + Member<ImageTrackList> tracks_; // Pending decode() requests. struct DecodeRequest : public GarbageCollected<DecodeRequest> {
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc index cf1eb51d..be014a3ee 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc
@@ -218,15 +218,15 @@ ASSERT_TRUE(tester.IsFulfilled()); } - EXPECT_EQ(decoder->type(), kImageType); - EXPECT_EQ(decoder->frameCount(), 2u); - EXPECT_EQ(decoder->repetitionCount(), 0u); - EXPECT_EQ(decoder->complete(), true); + const auto& tracks = decoder->tracks(); + ASSERT_EQ(tracks.length(), 1u); + EXPECT_EQ(tracks.AnonymousIndexedGetter(0)->animated(), true); + EXPECT_EQ(tracks.selectedTrack().value()->animated(), true); - auto tracks = decoder->tracks(); - EXPECT_EQ(tracks.size(), 1u); - EXPECT_EQ(tracks[0]->id(), 0u); - EXPECT_EQ(tracks[0]->animated(), true); + EXPECT_EQ(decoder->type(), kImageType); + EXPECT_EQ(tracks.selectedTrack().value()->frameCount(), 2u); + EXPECT_EQ(tracks.selectedTrack().value()->repetitionCount(), INFINITY); + EXPECT_EQ(decoder->complete(), true); { auto promise = decoder->decode(MakeOptions(0, true)); @@ -282,15 +282,15 @@ ASSERT_TRUE(tester.IsFulfilled()); } - EXPECT_EQ(decoder->type(), kImageType); - EXPECT_EQ(decoder->frameCount(), 2u); - EXPECT_EQ(decoder->repetitionCount(), 0u); - EXPECT_EQ(decoder->complete(), true); + const auto& tracks = decoder->tracks(); + ASSERT_EQ(tracks.length(), 1u); + EXPECT_EQ(tracks.AnonymousIndexedGetter(0)->animated(), true); + EXPECT_EQ(tracks.selectedTrack().value()->animated(), true); - auto tracks = decoder->tracks(); - EXPECT_EQ(tracks.size(), 1u); - EXPECT_EQ(tracks[0]->id(), 0u); - EXPECT_EQ(tracks[0]->animated(), true); + EXPECT_EQ(decoder->type(), kImageType); + EXPECT_EQ(tracks.selectedTrack().value()->frameCount(), 2u); + EXPECT_EQ(tracks.selectedTrack().value()->repetitionCount(), INFINITY); + EXPECT_EQ(decoder->complete(), true); { auto promise = decoder->decode(MakeOptions(0, true));
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_fuzzer.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_fuzzer.cc index 77f7f80..bb8e5ef 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_fuzzer.cc +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_fuzzer.cc
@@ -13,6 +13,8 @@ #include "third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.pb.h" #include "third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h" #include "third_party/blink/renderer/modules/webcodecs/image_decoder_external.h" +#include "third_party/blink/renderer/modules/webcodecs/image_track.h" +#include "third_party/blink/renderer/modules/webcodecs/image_track_list.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" @@ -115,10 +117,13 @@ case wc_fuzzer::ImageDecoderApiInvocation::kDecodeMetadata: image_decoder->decodeMetadata(); break; - case wc_fuzzer::ImageDecoderApiInvocation::kSelectTrack: - image_decoder->selectTrack(invocation.select_track().track_id(), - IGNORE_EXCEPTION_FOR_TESTING); + case wc_fuzzer::ImageDecoderApiInvocation::kSelectTrack: { + auto* track = image_decoder->tracks().AnonymousIndexedGetter( + invocation.select_track().track_id()); + if (track) + track->setSelected(true); break; + } case wc_fuzzer::ImageDecoderApiInvocation::API_NOT_SET: break; }
diff --git a/third_party/blink/renderer/modules/webcodecs/image_track.cc b/third_party/blink/renderer/modules/webcodecs/image_track.cc new file mode 100644 index 0000000..30139483 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/image_track.cc
@@ -0,0 +1,77 @@ +// 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 "third_party/blink/renderer/modules/webcodecs/image_track.h" + +#include "base/logging.h" +#include "third_party/blink/renderer/platform/image-decoders/image_animation.h" + +namespace blink { + +ImageTrack::ImageTrack(ImageTrackList* image_track_list, + wtf_size_t id, + uint32_t frame_count, + int repetition_count, + bool selected) + : id_(id), + image_track_list_(image_track_list), + frame_count_(frame_count), + repetition_count_(repetition_count), + selected_(selected) {} + +ImageTrack::~ImageTrack() = default; + +uint32_t ImageTrack::frameCount() const { + return frame_count_; +} + +bool ImageTrack::animated() const { + return frame_count_ > 1 || repetition_count_ != kAnimationNone; +} + +float ImageTrack::repetitionCount() const { + if (repetition_count_ == kAnimationNone || + repetition_count_ == kAnimationLoopOnce) { + return 0; + } + + if (repetition_count_ == kAnimationLoopInfinite) + return INFINITY; + + return repetition_count_; +} + +bool ImageTrack::selected() const { + return selected_; +} + +void ImageTrack::setSelected(bool selected) { + if (selected == selected_) + return; + + selected_ = selected; + + // If the track has been disconnected, a JS ref on the object may still exist + // and trigger calls here. We should do nothing in this case. + if (image_track_list_) + image_track_list_->OnTrackSelectionChanged(id_); +} + +void ImageTrack::UpdateTrack(uint32_t frame_count, int repetition_count) { + DCHECK(image_track_list_); + + const bool was_animated = animated(); + frame_count_ = frame_count; + repetition_count_ = repetition_count; + + // Animation state isn't allowed to change after construction. + DCHECK_EQ(was_animated, animated()); +} + +void ImageTrack::Trace(Visitor* visitor) const { + ScriptWrappable::Trace(visitor); + visitor->Trace(image_track_list_); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/image_track.h b/third_party/blink/renderer/modules/webcodecs/image_track.h new file mode 100644 index 0000000..391eed2 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/image_track.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 THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_IMAGE_TRACK_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_IMAGE_TRACK_H_ + +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/modules/webcodecs/image_track_list.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/heap/member.h" + +namespace blink { + +class MODULES_EXPORT ImageTrack final : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + ImageTrack(ImageTrackList* image_track_list, + wtf_size_t id, + uint32_t frame_count, + int repetition_count, + bool selected); + ~ImageTrack() override; + + // image_track.idl implementation. + uint32_t frameCount() const; + bool animated() const; + float repetitionCount() const; + bool selected() const; + void setSelected(bool selected); + + // Internal helpers for ImageTrackList. + void disconnect() { image_track_list_ = nullptr; } + void set_selected(bool selected) { selected_ = selected; } + void UpdateTrack(uint32_t frame_count, int repetition_count); + + // GarbageCollected override + void Trace(Visitor* visitor) const override; + + private: + const wtf_size_t id_; + Member<ImageTrackList> image_track_list_; + uint32_t frame_count_ = 0u; + int repetition_count_ = 0; + bool selected_ = false; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_IMAGE_TRACK_H_
diff --git a/third_party/blink/renderer/modules/webcodecs/image_track.idl b/third_party/blink/renderer/modules/webcodecs/image_track.idl index 74b3dd6..ec952ef8e 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_track.idl +++ b/third_party/blink/renderer/modules/webcodecs/image_track.idl
@@ -4,13 +4,28 @@ // https://github.com/WICG/web-codecs -[ImplementedAs=ImageTrackExternal] -dictionary ImageTrack { - // Numeric identifier which can be provided to ImageDecoder::selectTrack(). - required unsigned long id; +[ + Exposed=(Window,DedicatedWorker), + RuntimeEnabled=WebCodecs +] interface ImageTrack { + // The number of frames in the image. + // + // When decoding a ReadableStream with a format that has no fixed count, the + // value will increase as frames are received by the decoder. + readonly attribute unsigned long frameCount; // Indicates that this track has more than one frame. - required boolean animated; + readonly attribute boolean animated; - // TODO: Other metadata like frame size, kind, and label? Selected status? + // The image's preferred repetition count. Zero means play through only once, + // a value of N means play N + 1 times. Infinity means play forever. + readonly attribute unrestricted float repetitionCount; + + // Modify to choose this track in the image. Identical track selections will + // be ignored. + // + // Changing tracks will resolve all outstanding decode requests as rejected + // and reset any partially decoded frame state. Outstanding ImageDecodeResults + // and metadata decode promises will remain valid. + attribute boolean selected; };
diff --git a/third_party/blink/renderer/modules/webcodecs/image_track_list.cc b/third_party/blink/renderer/modules/webcodecs/image_track_list.cc new file mode 100644 index 0000000..cdb0273 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/image_track_list.cc
@@ -0,0 +1,73 @@ +// 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 "third_party/blink/renderer/modules/webcodecs/image_track_list.h" + +#include "base/logging.h" +#include "third_party/blink/renderer/modules/webcodecs/image_decoder_external.h" +#include "third_party/blink/renderer/modules/webcodecs/image_track.h" + +namespace blink { + +ImageTrackList::ImageTrackList(ImageDecoderExternal* image_decoder) + : image_decoder_(image_decoder) {} + +ImageTrackList::~ImageTrackList() = default; + +ImageTrack* ImageTrackList::AnonymousIndexedGetter(uint32_t index) const { + return index >= tracks_.size() ? nullptr : tracks_[index].Get(); +} + +int32_t ImageTrackList::selectedIndex() const { + return selected_track_id_.value_or(-1); +} + +base::Optional<ImageTrack*> ImageTrackList::selectedTrack() const { + if (!selected_track_id_) + return base::nullopt; + return tracks_[*selected_track_id_].Get(); +} + +void ImageTrackList::AddTrack(uint32_t frame_count, + int repetition_count, + bool selected) { + if (selected) { + DCHECK(!selected_track_id_.has_value()); + selected_track_id_ = tracks_.size(); + } + + tracks_.push_back(MakeGarbageCollected<ImageTrack>( + this, tracks_.size(), frame_count, repetition_count, selected)); +} + +void ImageTrackList::OnTrackSelectionChanged(wtf_size_t index) { + DCHECK(image_decoder_); + DCHECK_LT(index, tracks_.size()); + + if (selected_track_id_) + tracks_[*selected_track_id_]->set_selected(false); + + if (tracks_[index]->selected()) + selected_track_id_ = index; + else + selected_track_id_.reset(); + + image_decoder_->UpdateSelectedTrack(); +} + +void ImageTrackList::Disconnect() { + for (auto& track : tracks_) + track->disconnect(); + image_decoder_ = nullptr; + selected_track_id_.reset(); + tracks_.clear(); +} + +void ImageTrackList::Trace(Visitor* visitor) const { + ScriptWrappable::Trace(visitor); + visitor->Trace(image_decoder_); + visitor->Trace(tracks_); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/image_track_list.h b/third_party/blink/renderer/modules/webcodecs/image_track_list.h new file mode 100644 index 0000000..61fc85a --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/image_track_list.h
@@ -0,0 +1,53 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_IMAGE_TRACK_LIST_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_IMAGE_TRACK_LIST_H_ + +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/heap/member.h" + +namespace blink { +class ImageDecoderExternal; +class ImageTrack; + +class MODULES_EXPORT ImageTrackList final : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit ImageTrackList(ImageDecoderExternal* image_decoder); + ~ImageTrackList() override; + + // image_track_list.idl implementation. + uint32_t length() const { return tracks_.size(); } + ImageTrack* AnonymousIndexedGetter(uint32_t index) const; + int32_t selectedIndex() const; + base::Optional<ImageTrack*> selectedTrack() const; + + bool IsEmpty() const { return tracks_.IsEmpty(); } + + // Helper method for ImageDecoder to add tracks. Only one track may be marked + // as selected at any given time. + void AddTrack(uint32_t frame_count, int repetition_count, bool selected); + + // Called by ImageTrack entries to update their track selection status. + void OnTrackSelectionChanged(wtf_size_t index); + + // Disconnects and clears the ImageTrackList. Disconnecting releases all + // Member<> references held by the ImageTrackList and ImageTrack. + void Disconnect(); + + // GarbageCollected override + void Trace(Visitor* visitor) const override; + + private: + Member<ImageDecoderExternal> image_decoder_; + HeapVector<Member<ImageTrack>> tracks_; + base::Optional<wtf_size_t> selected_track_id_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_IMAGE_TRACK_LIST_H_
diff --git a/third_party/blink/renderer/modules/webcodecs/image_track_list.idl b/third_party/blink/renderer/modules/webcodecs/image_track_list.idl new file mode 100644 index 0000000..0296663 --- /dev/null +++ b/third_party/blink/renderer/modules/webcodecs/image_track_list.idl
@@ -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. + +// https://github.com/WICG/web-codecs + +[ + Exposed=(Window,DedicatedWorker), + RuntimeEnabled=WebCodecs +] interface ImageTrackList { + getter ImageTrack(unsigned long index); + readonly attribute unsigned long length; + + // Index of the currently selected track or -1 if no track is selected. + readonly attribute long selectedIndex; + + // Helper accessor for the currently selected track. + readonly attribute ImageTrack? selectedTrack; +};
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index be9b6fa..42dd83d 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -541,6 +541,16 @@ case GL_DEPTH32F_STENCIL8: case GL_STENCIL_INDEX8: break; + case GL_R16_EXT: + case GL_RG16_EXT: + case GL_RGBA16_EXT: + if (!ExtensionEnabled(kEXTTextureNorm16Name)) { + SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", + "invalid internalformat when EXT_texture_norm16 " + "is not enabled"); + return ScriptValue::CreateNull(script_state->GetIsolate()); + } + break; case GL_R16F: case GL_RG16F: case GL_RGBA16F:
diff --git a/third_party/blink/tools/blinkpy/common/config/builders.json b/third_party/blink/tools/blinkpy/common/config/builders.json index 8408bb0..2cdf8bc 100644 --- a/third_party/blink/tools/blinkpy/common/config/builders.json +++ b/third_party/blink/tools/blinkpy/common/config/builders.json
@@ -24,11 +24,6 @@ "port_name": "mac-mac10.13", "specifiers": ["Mac10.13", "Release"] }, - "Mac10.13 Tests (dbg)": { - "master": "chromium.mac", - "port_name": "mac-mac10.13", - "specifiers": ["Mac10.13", "Debug"] - }, "Mac10.14 Tests": { "master": "chromium.mac", "port_name": "mac-mac10.14",
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt deleted file mode 100644 index 96172b1..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt +++ /dev/null
@@ -1,304 +0,0 @@ -This is a testharness.js-based test. -Found 100 tests; 0 PASS, 100 FAIL, 0 TIMEOUT, 0 NOTRUN. -FAIL .grid 1 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 1 / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 1 / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 2 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 2 / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 2 / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 3 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 3 / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 3 / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 4 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / auto / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / auto / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 5 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / 2 / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / 2 / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 6 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / 3 / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / 3 / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 7 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / auto / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / auto / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 8 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 2 / auto / 3 / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 2 / auto / 3 / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 9 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 2 / auto / auto / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 2 / auto / auto / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 10 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 3 / auto / auto / 1; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="0" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 3 / auto / auto / 1; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 11 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 1 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 1 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 12 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 2 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 2 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 13 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 3 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 3 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 14 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / auto / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / auto / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 15 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / 2 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / 2 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 16 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / 3 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / 3 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 17 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / auto / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / auto / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 18 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 2 / auto / 3 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 2 / auto / 3 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 19 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 2 / auto / auto / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 2 / auto / auto / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 20 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 3 / auto / auto / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="145" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 3 / auto / auto / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 21 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 1 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 1 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 22 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 2 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 2 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 23 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 24 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 25 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / 2 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / 2 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 26 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 27 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 28 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 2 / auto / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 2 / auto / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 29 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 2 / auto / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 2 / auto / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 30 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 3 / auto / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="445" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 3 / auto / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 31 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 1 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 1 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 32 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 2 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 2 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 33 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 34 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: auto / auto / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: auto / auto / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 35 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / 2 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / 2 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 36 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 37 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 1 / auto / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 1 / auto / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 38 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 2 / auto / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 2 / auto / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 39 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 2 / auto / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 2 / auto / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 40 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="45" style="grid-area: 3 / auto / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="510" data-expected-height="50" data-offset-x="25" data-offset-y="195" style="grid-area: 3 / auto / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 41 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 1 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 1 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 42 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 2 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 2 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 43 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 3 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 3 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 44 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / auto / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / auto / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 45 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / 2 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / 2 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 46 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / 3 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / 3 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 47 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / auto / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / auto / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 48 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 2 / 1 / 3 / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 2 / 1 / 3 / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 49 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 2 / 1 / auto / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 2 / 1 / auto / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 50 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 3 / 1 / auto / 2; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="140" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 3 / 1 / auto / 2; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 51 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 1 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 1 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 52 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 2 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 2 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 53 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 54 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 55 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / 2 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / 2 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 56 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 57 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 58 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 2 / 1 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 2 / 1 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 59 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 2 / 1 / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 2 / 1 / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 60 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 3 / 1 / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="440" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 3 / 1 / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 61 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 1 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 1 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 62 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 63 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 64 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: auto / 1 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: auto / 1 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 65 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 66 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 67 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 1 / 1 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 1 / 1 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 68 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 2 / 1 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 2 / 1 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 69 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 2 / 1 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 2 / 1 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 70 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="45" style="grid-area: 3 / 1 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="505" data-expected-height="50" data-offset-x="30" data-offset-y="195" style="grid-area: 3 / 1 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 71 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: auto / 2 / 1 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: auto / 2 / 1 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 72 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: auto / 2 / 2 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: auto / 2 / 2 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 73 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: auto / 2 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: auto / 2 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 74 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: auto / 2 / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: auto / 2 / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 75 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 1 / 2 / 2 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 1 / 2 / 2 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 76 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 1 / 2 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 1 / 2 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 77 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 1 / 2 / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 1 / 2 / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 78 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 2 / 2 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 2 / 2 / 3 / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 79 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 2 / 2 / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 2 / 2 / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 80 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 3 / 2 / auto / 3; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="240" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 3 / 2 / auto / 3; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 81 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: auto / 2 / 1 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: auto / 2 / 1 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 82 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: auto / 2 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: auto / 2 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 83 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: auto / 2 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: auto / 2 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 84 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: auto / 2 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: auto / 2 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 85 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 1 / 2 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 1 / 2 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 86 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 1 / 2 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 1 / 2 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 87 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 1 / 2 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 1 / 2 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 88 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 2 / 2 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 2 / 2 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 89 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 2 / 2 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 2 / 2 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 90 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="45" style="grid-area: 3 / 2 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="305" data-expected-height="50" data-offset-x="230" data-offset-y="195" style="grid-area: 3 / 2 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 91 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: auto / 3 / 1 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: auto / 3 / 1 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 92 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: auto / 3 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: auto / 3 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 93 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: auto / 3 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: auto / 3 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 94 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: auto / 3 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: auto / 3 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 95 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: 1 / 3 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: 1 / 3 / 2 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 96 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: 1 / 3 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: 1 / 3 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 97 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: 1 / 3 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: 1 / 3 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 98 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: 2 / 3 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: 2 / 3 / 3 / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 99 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: 2 / 3 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: 2 / 3 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -FAIL .grid 100 assert_equals: -<div class="grid"><div style="grid-area: 1 / 1 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="45" style="grid-area: 3 / 3 / auto / auto; inset: auto 35px auto 25px;">XX</div></div><div style="grid-area: 2 / 2 / auto / auto;">X<br>XX<div class="abspos orthogonal" data-expected-width="5" data-expected-height="50" data-offset-x="530" data-offset-y="195" style="grid-area: 3 / 3 / auto / auto; inset: auto 35px auto 25px;">XX</div></div></div> -offsetTop expected 45 but got 55 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.tentative-expected.txt deleted file mode 100644 index b669306..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.tentative-expected.txt +++ /dev/null
@@ -1,144 +0,0 @@ -This is a testharness.js-based test. -Found 140 tests; 105 PASS, 35 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS display: grid -PASS display: inline-grid -PASS grid-template-columns -FAIL grid-template-columns.initial assert_equals: initial value of grid-template-columns should be none expected "none" but got "150px" -FAIL grid-template-columns.none assert_equals: none expected "none" but got "150px" -PASS grid-template-columns.<line-names> -PASS grid-template-columns.<track-size>.auto -PASS grid-template-columns.<track-size>.<track-breadth>.<length> -PASS grid-template-columns.<track-size>.<track-breadth>.<percentage> -PASS grid-template-columns.<track-size>.<track-breadth>.<flex> -PASS grid-template-columns.<track-size>.<track-breadth>.min-content -PASS grid-template-columns.<track-size>.<track-breadth>.max-content -PASS grid-template-columns.<track-size>.<track-breadth>.minmax() -FAIL grid-template-columns.reset assert_equals: reset expected "none" but got "150px" -PASS grid-template-rows -FAIL grid-template-rows.initial assert_equals: initial value of grid-template-rows should be none expected "none" but got "50px 50px 50px" -FAIL grid-template-rows.none assert_equals: none expected "none" but got "50px 50px 50px" -FAIL grid-template-rows.<line-names> assert_equals: <line-names> expected "[a] 50px [b] 50px [c]" but got "[a] 50px [b] 50px [c] 50px" -FAIL grid-template-rows.<track-size>.auto assert_equals: <track-size>.auto expected "50px" but got "50px 50px 50px" -FAIL grid-template-rows.<track-size>.<track-breadth>.<length> assert_equals: <track-size>.<track-breadth>.<length> expected "100px" but got "100px 50px 50px" -FAIL grid-template-rows.<track-size>.<track-breadth>.<percentage> assert_equals: <track-size>.<track-breadth>.<percentage> expected "150px" but got "150px 50px 50px" -FAIL grid-template-rows.<track-size>.<track-breadth>.<flex> assert_equals: <track-size>.<track-breadth>.<flex> expected "50px" but got "50px 50px 50px" -FAIL grid-template-rows.<track-size>.<track-breadth>.min-content assert_equals: <track-size>.<track-breadth>.min-content expected "50px" but got "50px 50px 50px" -FAIL grid-template-rows.<track-size>.<track-breadth>.max-content assert_equals: <track-size>.<track-breadth>.max-content expected "50px" but got "50px 50px 50px" -FAIL grid-template-rows.<track-size>.<track-breadth>.minmax() assert_equals: <track-size>.<track-breadth>.minmax() expected "200px" but got "200px 50px 50px" -FAIL grid-template-rows.reset assert_equals: reset expected "none" but got "50px 50px 50px" -PASS grid-template-areas -PASS grid-template-areas.initial -PASS grid-template-areas.none -PASS grid-template-areas.<string>+ -PASS grid-template-areas.reset -PASS grid-template -FAIL grid-template.initial assert_equals: initial value of grid-template should be none expected "none" but got "50px 50px 50px / 150px / none" -FAIL grid-template.none assert_equals: none expected "none" but got "50px 50px 50px / 150px / none" -FAIL grid-template.<grid-template-rows> / <grid-template-columns> assert_equals: <grid-template-rows> / <grid-template-columns> expected "100px 100px / 200px 200px" but got "" -FAIL grid-template.<line-names> assert_equals: <line-names> expected "[a] auto [b] auto [c] / [d] auto [e] auto [f]" but got "" -FAIL grid-template.<string>+ assert_equals: <string>+ expected "\"a b\" \"a b\"" but got "" -FAIL grid-template.<string><track-size>+ assert_equals: <string><track-size>+ expected "100px / \"a b\" 50px" but got "" -FAIL grid-template.reset assert_equals: reset expected "none" but got "50px 50px 50px / 150px / none" -PASS grid-auto-columns -PASS grid-auto-columns.initial -PASS grid-auto-columns.<track-size>.auto -PASS grid-auto-columns.<track-size>.<track-breadth>.<length> -PASS grid-auto-columns.<track-size>.<track-breadth>.<percentage> -PASS grid-auto-columns.<track-size>.<track-breadth>.<flex> -PASS grid-auto-columns.<track-size>.<track-breadth>.min-content -PASS grid-auto-columns.<track-size>.<track-breadth>.max-content -PASS grid-auto-columns.<track-size>.<track-breadth>.minmax() -PASS grid-auto-columns.reset -PASS grid-auto-rows -PASS grid-auto-rows.initial -PASS grid-auto-rows.<track-size>.auto -PASS grid-auto-rows.<track-size>.<track-breadth>.<length> -PASS grid-auto-rows.<track-size>.<track-breadth>.<percentage> -PASS grid-auto-rows.<track-size>.<track-breadth>.<flex> -PASS grid-auto-rows.<track-size>.<track-breadth>.min-content -PASS grid-auto-rows.<track-size>.<track-breadth>.max-content -PASS grid-auto-rows.<track-size>.<track-breadth>.minmax() -PASS grid-auto-rows.reset -PASS grid-auto-flow -PASS grid-auto-flow.initial -PASS grid-auto-flow.row -PASS grid-auto-flow.column -FAIL grid-auto-flow.dense assert_equals: dense expected "dense" but got "row dense" -FAIL grid-auto-flow.row dense assert_equals: row dense expected "dense" but got "row dense" -PASS grid-auto-flow.column dense -PASS grid-auto-flow.reset -PASS grid-row-start -PASS grid-row-start.initial -PASS grid-row-start.auto -PASS grid-row-start.<custom-ident> -PASS grid-row-start.<integer> -PASS grid-row-start.<integer> <ident> -PASS grid-row-start.span <integer> -PASS grid-row-start.span <custom-ident> -PASS grid-row-start.span <integer> <custom-ident> -PASS grid-row-start.reset -PASS grid-column-start -PASS grid-column-start.initial -PASS grid-column-start.auto -PASS grid-column-start.<custom-ident> -PASS grid-column-start.<integer> -PASS grid-column-start.<integer> <ident> -PASS grid-column-start.span <integer> -PASS grid-column-start.span <custom-ident> -PASS grid-column-start.span <integer> <custom-ident> -PASS grid-column-start.reset -PASS grid-row-end -PASS grid-row-end.initial -PASS grid-row-end.auto -PASS grid-row-end.<custom-ident> -PASS grid-row-end.<integer> -PASS grid-row-end.<integer> <ident> -PASS grid-row-end.span <integer> -PASS grid-row-end.span <custom-ident> -PASS grid-row-end.span <integer> <custom-ident> -PASS grid-row-end.reset -PASS grid-column-end -PASS grid-column-end.initial -PASS grid-column-end.auto -PASS grid-column-end.<custom-ident> -PASS grid-column-end.<integer> -PASS grid-column-end.<integer> <ident> -PASS grid-column-end.span <integer> -PASS grid-column-end.span <custom-ident> -PASS grid-column-end.span <integer> <custom-ident> -PASS grid-column-end.reset -PASS grid-column -FAIL grid-column.initial assert_equals: initial value of grid-column should be auto expected "auto" but got "auto / auto" -FAIL grid-column.auto assert_equals: auto expected "auto" but got "auto / auto" -PASS grid-column.<custom-ident> -FAIL grid-column.<integer> start assert_equals: <integer> start expected "1" but got "1 / auto" -PASS grid-column.<integer> -PASS grid-column.<integer> <ident> -PASS grid-column.span <integer> -PASS grid-column.span <custom-ident> -PASS grid-column.span <integer> <custom-ident> -FAIL grid-column.reset assert_equals: reset expected "auto" but got "auto / auto" -PASS grid-row -FAIL grid-row.initial assert_equals: initial value of grid-row should be auto expected "auto" but got "auto / auto" -FAIL grid-row.auto assert_equals: auto expected "auto" but got "auto / auto" -PASS grid-row.<custom-ident> -FAIL grid-row.<integer> start assert_equals: <integer> start expected "1" but got "1 / auto" -PASS grid-row.<integer> -PASS grid-row.<integer> <ident> -PASS grid-row.span <integer> -PASS grid-row.span <custom-ident> -PASS grid-row.span <integer> <custom-ident> -FAIL grid-row.reset assert_equals: reset expected "auto" but got "auto / auto" -PASS grid-area -FAIL grid-area.initial assert_equals: initial value of grid-area should be auto expected "auto" but got "auto / auto / auto / auto" -FAIL grid-area.auto assert_equals: auto expected "auto" but got "auto / auto / auto / auto" -PASS grid-area.<custom-ident> -FAIL grid-area.<integer> start assert_equals: <integer> start expected "1 / 2" but got "1 / 2 / auto / auto" -PASS grid-area.<integer> -PASS grid-area.<integer> <ident> -PASS grid-area.span <integer> -PASS grid-area.span <custom-ident> -PASS grid-area.span <integer> <custom-ident> -FAIL grid-area.reset assert_equals: reset expected "auto" but got "auto / auto / auto / auto" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry.tentative/masonry-grid-template-columns-computed-withcontent-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry.tentative/masonry-grid-template-columns-computed-withcontent-expected.txt deleted file mode 100644 index 1b67813e..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry.tentative/masonry-grid-template-columns-computed-withcontent-expected.txt +++ /dev/null
@@ -1,31 +0,0 @@ -This is a testharness.js-based test. -FAIL Property grid-template-rows value 'masonry' assert_true: 'masonry' is a supported value for grid-template-rows. expected true got false -FAIL Property grid-template-columns value 'none' assert_equals: expected "none" but got "300px" -PASS Property grid-template-columns value '20%' -PASS Property grid-template-columns value 'calc(-0.5em + 10px)' -PASS Property grid-template-columns value 'calc(0.5em + 10px)' -PASS Property grid-template-columns value 'calc(30% + 40px)' -PASS Property grid-template-columns value '5fr' -PASS Property grid-template-columns value 'min-content' -PASS Property grid-template-columns value 'max-content' -PASS Property grid-template-columns value 'auto' -PASS Property grid-template-columns value 'minmax(10px, auto)' -PASS Property grid-template-columns value 'minmax(20%, max-content)' -PASS Property grid-template-columns value 'minmax(min-content, calc(-0.5em + 10px))' -PASS Property grid-template-columns value 'minmax(auto, 0)' -PASS Property grid-template-columns value 'fit-content(70px)' -PASS Property grid-template-columns value 'fit-content(20%)' -PASS Property grid-template-columns value 'fit-content(calc(-0.5em + 10px))' -PASS Property grid-template-columns value 'repeat(1, 10px)' -PASS Property grid-template-columns value 'repeat(1, [one two] 20%)' -PASS Property grid-template-columns value 'repeat(2, minmax(10px, auto))' -PASS Property grid-template-columns value 'repeat(2, fit-content(20%) [three four] 30px 40px [five six])' -PASS Property grid-template-columns value 'min-content repeat(5, minmax(10px, auto))' -PASS Property grid-template-columns value '[] 150px [] 1fr []' -PASS Property grid-template-columns value 'repeat(auto-fill, 200px)' -PASS Property grid-template-columns value 'repeat(auto-fit, [one] 20%)' -PASS Property grid-template-columns value 'repeat(auto-fill, minmax(100px, 5fr) [two])' -PASS Property grid-template-columns value 'repeat(auto-fit, [three] minmax(max-content, 6em) [four])' -PASS Property grid-template-columns value '[one] repeat(2, minmax(50px, auto)) [two] 30px [three] repeat(auto-fill, 10px) 40px [four five] repeat(2, minmax(200px, auto)) [six]' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry.tentative/masonry-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry.tentative/masonry-parsing-expected.txt deleted file mode 100644 index 650ae12e..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry.tentative/masonry-parsing-expected.txt +++ /dev/null
@@ -1,71 +0,0 @@ -This is a testharness.js-based test. -Found 67 tests; 27 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. -FAIL e.style['grid-template-columns'] = "masonry" should set the property value assert_not_equals: property should be set got disallowed value "" -PASS e.style['grid-template-columns'] = "masonry []" should not set the property value -PASS e.style['grid-template-columns'] = "masonry [foo] 40px" should not set the property value -PASS e.style['grid-template-columns'] = "masonry 40px" should not set the property value -PASS e.style['grid-template-columns'] = "[foo] masonry" should not set the property value -PASS e.style['grid-template-columns'] = "0px masonry" should not set the property value -PASS e.style['grid-template-columns'] = "masonry masonry" should not set the property value -PASS e.style['grid-template-columns'] = "subgrid masonry" should not set the property value -PASS e.style['grid-template-columns'] = "masonry subgrid" should not set the property value -PASS e.style['grid-template-columns'] = "masonry repeat(1, [])" should not set the property value -PASS e.style['grid-template-columns'] = "masonry repeat(auto-fill, [])" should not set the property value -PASS e.style['grid-template-columns'] = "masonry / none" should not set the property value -FAIL e.style['grid-template-rows'] = "masonry" should set the property value assert_not_equals: property should be set got disallowed value "" -PASS e.style['grid-template-rows'] = "masonry []" should not set the property value -PASS e.style['grid-template-rows'] = "masonry [foo] 40px" should not set the property value -PASS e.style['grid-template-rows'] = "masonry 40px" should not set the property value -PASS e.style['grid-template-rows'] = "[foo] masonry" should not set the property value -PASS e.style['grid-template-rows'] = "0px masonry" should not set the property value -PASS e.style['grid-template-rows'] = "masonry masonry" should not set the property value -PASS e.style['grid-template-rows'] = "subgrid masonry" should not set the property value -PASS e.style['grid-template-rows'] = "masonry subgrid" should not set the property value -PASS e.style['grid-template-rows'] = "masonry repeat(1, [])" should not set the property value -PASS e.style['grid-template-rows'] = "masonry repeat(auto-fill, [])" should not set the property value -PASS e.style['grid-template-rows'] = "masonry / none" should not set the property value -FAIL e.style['grid-template'] = "masonry / masonry" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid-template'] = "masonry / masonry" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "masonry" but got "" -FAIL e.style['grid-template'] = "masonry / masonry" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "masonry" but got "" -FAIL e.style['grid-template'] = "masonry / masonry" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid-template'] = "masonry / subgrid [foo]" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid-template'] = "masonry / subgrid [foo]" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "subgrid [foo]" but got "" -FAIL e.style['grid-template'] = "masonry / subgrid [foo]" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "masonry" but got "" -FAIL e.style['grid-template'] = "masonry / subgrid [foo]" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid-template'] = "10px / masonry" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid-template'] = "10px / masonry" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "masonry" but got "" -FAIL e.style['grid-template'] = "10px / masonry" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "10px" but got "" -FAIL e.style['grid-template'] = "10px / masonry" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid'] = "masonry / masonry" should set grid-auto-columns assert_equals: grid-auto-columns should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-auto-flow assert_equals: grid-auto-flow should be canonical expected "row" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-auto-rows assert_equals: grid-auto-rows should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "masonry" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "masonry" but got "" -FAIL e.style['grid'] = "masonry / masonry" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-auto-columns assert_equals: grid-auto-columns should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-auto-flow assert_equals: grid-auto-flow should be canonical expected "row" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-auto-rows assert_equals: grid-auto-rows should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "subgrid [foo]" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "masonry" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid'] = "10px / masonry" should set grid-auto-columns assert_equals: grid-auto-columns should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-auto-flow assert_equals: grid-auto-flow should be canonical expected "row" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-auto-rows assert_equals: grid-auto-rows should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "masonry" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "10px" but got "" -FAIL e.style['grid'] = "10px / masonry" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['masonry-auto-flow'] = "pack" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['masonry-auto-flow'] = "pack ordered" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['masonry-auto-flow'] = "ordered next" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['masonry-auto-flow'] = "next definite-first" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['masonry-auto-flow'] = "definite-first pack" should set the property value assert_not_equals: property should be set got disallowed value "" -PASS e.style['masonry-auto-flow'] = "auto" should not set the property value -PASS e.style['masonry-auto-flow'] = "none" should not set the property value -PASS e.style['masonry-auto-flow'] = "10px" should not set the property value -PASS e.style['masonry-auto-flow'] = "row" should not set the property value -PASS e.style['masonry-auto-flow'] = "dense" should not set the property value -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent-expected.txt deleted file mode 100644 index 1b67813e..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent-expected.txt +++ /dev/null
@@ -1,31 +0,0 @@ -This is a testharness.js-based test. -FAIL Property grid-template-rows value 'masonry' assert_true: 'masonry' is a supported value for grid-template-rows. expected true got false -FAIL Property grid-template-columns value 'none' assert_equals: expected "none" but got "300px" -PASS Property grid-template-columns value '20%' -PASS Property grid-template-columns value 'calc(-0.5em + 10px)' -PASS Property grid-template-columns value 'calc(0.5em + 10px)' -PASS Property grid-template-columns value 'calc(30% + 40px)' -PASS Property grid-template-columns value '5fr' -PASS Property grid-template-columns value 'min-content' -PASS Property grid-template-columns value 'max-content' -PASS Property grid-template-columns value 'auto' -PASS Property grid-template-columns value 'minmax(10px, auto)' -PASS Property grid-template-columns value 'minmax(20%, max-content)' -PASS Property grid-template-columns value 'minmax(min-content, calc(-0.5em + 10px))' -PASS Property grid-template-columns value 'minmax(auto, 0)' -PASS Property grid-template-columns value 'fit-content(70px)' -PASS Property grid-template-columns value 'fit-content(20%)' -PASS Property grid-template-columns value 'fit-content(calc(-0.5em + 10px))' -PASS Property grid-template-columns value 'repeat(1, 10px)' -PASS Property grid-template-columns value 'repeat(1, [one two] 20%)' -PASS Property grid-template-columns value 'repeat(2, minmax(10px, auto))' -PASS Property grid-template-columns value 'repeat(2, fit-content(20%) [three four] 30px 40px [five six])' -PASS Property grid-template-columns value 'min-content repeat(5, minmax(10px, auto))' -PASS Property grid-template-columns value '[] 150px [] 1fr []' -PASS Property grid-template-columns value 'repeat(auto-fill, 200px)' -PASS Property grid-template-columns value 'repeat(auto-fit, [one] 20%)' -PASS Property grid-template-columns value 'repeat(auto-fill, minmax(100px, 5fr) [two])' -PASS Property grid-template-columns value 'repeat(auto-fit, [three] minmax(max-content, 6em) [four])' -PASS Property grid-template-columns value '[one] repeat(2, minmax(50px, auto)) [two] 30px [three] repeat(auto-fill, 10px) 40px [four five] repeat(2, minmax(200px, auto)) [six]' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-parsing-expected.txt deleted file mode 100644 index 650ae12e..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-parsing-expected.txt +++ /dev/null
@@ -1,71 +0,0 @@ -This is a testharness.js-based test. -Found 67 tests; 27 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. -FAIL e.style['grid-template-columns'] = "masonry" should set the property value assert_not_equals: property should be set got disallowed value "" -PASS e.style['grid-template-columns'] = "masonry []" should not set the property value -PASS e.style['grid-template-columns'] = "masonry [foo] 40px" should not set the property value -PASS e.style['grid-template-columns'] = "masonry 40px" should not set the property value -PASS e.style['grid-template-columns'] = "[foo] masonry" should not set the property value -PASS e.style['grid-template-columns'] = "0px masonry" should not set the property value -PASS e.style['grid-template-columns'] = "masonry masonry" should not set the property value -PASS e.style['grid-template-columns'] = "subgrid masonry" should not set the property value -PASS e.style['grid-template-columns'] = "masonry subgrid" should not set the property value -PASS e.style['grid-template-columns'] = "masonry repeat(1, [])" should not set the property value -PASS e.style['grid-template-columns'] = "masonry repeat(auto-fill, [])" should not set the property value -PASS e.style['grid-template-columns'] = "masonry / none" should not set the property value -FAIL e.style['grid-template-rows'] = "masonry" should set the property value assert_not_equals: property should be set got disallowed value "" -PASS e.style['grid-template-rows'] = "masonry []" should not set the property value -PASS e.style['grid-template-rows'] = "masonry [foo] 40px" should not set the property value -PASS e.style['grid-template-rows'] = "masonry 40px" should not set the property value -PASS e.style['grid-template-rows'] = "[foo] masonry" should not set the property value -PASS e.style['grid-template-rows'] = "0px masonry" should not set the property value -PASS e.style['grid-template-rows'] = "masonry masonry" should not set the property value -PASS e.style['grid-template-rows'] = "subgrid masonry" should not set the property value -PASS e.style['grid-template-rows'] = "masonry subgrid" should not set the property value -PASS e.style['grid-template-rows'] = "masonry repeat(1, [])" should not set the property value -PASS e.style['grid-template-rows'] = "masonry repeat(auto-fill, [])" should not set the property value -PASS e.style['grid-template-rows'] = "masonry / none" should not set the property value -FAIL e.style['grid-template'] = "masonry / masonry" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid-template'] = "masonry / masonry" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "masonry" but got "" -FAIL e.style['grid-template'] = "masonry / masonry" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "masonry" but got "" -FAIL e.style['grid-template'] = "masonry / masonry" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid-template'] = "masonry / subgrid [foo]" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid-template'] = "masonry / subgrid [foo]" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "subgrid [foo]" but got "" -FAIL e.style['grid-template'] = "masonry / subgrid [foo]" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "masonry" but got "" -FAIL e.style['grid-template'] = "masonry / subgrid [foo]" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid-template'] = "10px / masonry" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid-template'] = "10px / masonry" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "masonry" but got "" -FAIL e.style['grid-template'] = "10px / masonry" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "10px" but got "" -FAIL e.style['grid-template'] = "10px / masonry" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid'] = "masonry / masonry" should set grid-auto-columns assert_equals: grid-auto-columns should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-auto-flow assert_equals: grid-auto-flow should be canonical expected "row" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-auto-rows assert_equals: grid-auto-rows should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "masonry" but got "" -FAIL e.style['grid'] = "masonry / masonry" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "masonry" but got "" -FAIL e.style['grid'] = "masonry / masonry" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-auto-columns assert_equals: grid-auto-columns should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-auto-flow assert_equals: grid-auto-flow should be canonical expected "row" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-auto-rows assert_equals: grid-auto-rows should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "subgrid [foo]" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "masonry" but got "" -FAIL e.style['grid'] = "masonry / subgrid [foo]" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['grid'] = "10px / masonry" should set grid-auto-columns assert_equals: grid-auto-columns should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-auto-flow assert_equals: grid-auto-flow should be canonical expected "row" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-auto-rows assert_equals: grid-auto-rows should be canonical expected "auto" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-template-areas assert_equals: grid-template-areas should be canonical expected "none" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-template-columns assert_equals: grid-template-columns should be canonical expected "masonry" but got "" -FAIL e.style['grid'] = "10px / masonry" should set grid-template-rows assert_equals: grid-template-rows should be canonical expected "10px" but got "" -FAIL e.style['grid'] = "10px / masonry" should not set unrelated longhands assert_true: expected true got false -FAIL e.style['masonry-auto-flow'] = "pack" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['masonry-auto-flow'] = "pack ordered" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['masonry-auto-flow'] = "ordered next" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['masonry-auto-flow'] = "next definite-first" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['masonry-auto-flow'] = "definite-first pack" should set the property value assert_not_equals: property should be set got disallowed value "" -PASS e.style['masonry-auto-flow'] = "auto" should not set the property value -PASS e.style['masonry-auto-flow'] = "none" should not set the property value -PASS e.style['masonry-auto-flow'] = "10px" should not set the property value -PASS e.style['masonry-auto-flow'] = "row" should not set the property value -PASS e.style['masonry-auto-flow'] = "dense" should not set the property value -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/dynamic_table_layout_crash.html b/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/dynamic_table_layout_crash.html new file mode 100644 index 0000000..cc28f3bf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/dynamic_table_layout_crash.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<table id="target" style="border: solid; border-collapse: collapse; table-layout: fixed; width: 50px;"> + <tr><td style="background: lime;">hi</td></tr> + <td colspan=3>there</td> +</table> +<script> +document.body.offsetTop; +document.getElementById('target').style.tableLayout = 'auto'; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/README.md b/third_party/blink/web_tests/external/wpt/webcodecs/README.md index d9055dc3..46de814 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/README.md +++ b/third_party/blink/web_tests/external/wpt/webcodecs/README.md
@@ -40,6 +40,12 @@ gifski -o four-colors-flip.gif four-colors*.png ``` +### four-colors-flip.avif +``` +ffmpeg -i four-colors-flip.gif -vcodec libaom-av1 -crf 16 four-colors-flip.mp4 +mp4box -add-image ref:primary:tk=1:samp=1 -ab avis -ab avif -ab miaf -brand avis four-colors-flip.mp4 -out four-colors-flip.avif +``` + ### four-colors.jpg Used [Sqoosh.app](https://squoosh.app/) with MozJPEG compression then used exiftool to add an orientation marker.
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/four-colors-flip.avif b/third_party/blink/web_tests/external/wpt/webcodecs/four-colors-flip.avif new file mode 100644 index 0000000..2927e3a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webcodecs/four-colors-flip.avif Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/image-decoder.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/image-decoder.any.js index c1780d5..08ef96f 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/image-decoder.any.js +++ b/third_party/blink/web_tests/external/wpt/webcodecs/image-decoder.any.js
@@ -1,15 +1,24 @@ // META: global=window,dedicatedworker // META: script=/webcodecs/image-decoder-utils.js -function testFourColorsDecode(filename, mimeType) { +function testFourColorsDecode(filename, mimeType, preferAnimation) { + var decoder = null; return fetch(filename) .then(response => { - let decoder = new ImageDecoder({data: response.body, type: mimeType}); + decoder = new ImageDecoder({ + data: response.body, + type: mimeType, + preferAnimation: preferAnimation + }); return decoder.decode(); }) .then(result => { assert_equals(result.image.displayWidth, 320); assert_equals(result.image.displayHeight, 240); + if (preferAnimation !== undefined) { + assert_greater_than(decoder.tracks.length, 1); + assert_equals(preferAnimation, decoder.tracks.selectedTrack.animated); + } let canvas = new OffscreenCanvas( result.image.displayWidth, result.image.displayHeight); @@ -79,6 +88,14 @@ }, 'Test AVIF image decoding.'); promise_test(t => { + return testFourColorsDecode('four-colors-flip.avif', 'image/avif', false); +}, 'Test multi-track AVIF image decoding w/ preferAnimation=false.'); + +promise_test(t => { + return testFourColorsDecode('four-colors-flip.avif', 'image/avif', true); +}, 'Test multi-track AVIF image decoding w/ preferAnimation=true.'); + +promise_test(t => { return testFourColorsDecode('four-colors.webp', 'image/webp'); }, 'Test WEBP image decoding.'); @@ -101,6 +118,73 @@ }); }, 'Test invalid mime type rejects decodeMetadata() requests'); +promise_test(t => { + var decoder = null; + + return fetch('four-colors.png') + .then(response => { + decoder = new ImageDecoder({data: response.body, type: 'image/png'}); + return decoder.decodeMetadata(); + }) + .then(_ => { + decoder.tracks.selectedTrack.selected = false; + assert_equals(decoder.tracks.selectedIndex, -1); + assert_equals(decoder.tracks.selectedTrack, null); + return decoder.decodeMetadata(); + }) + .then(_ => { + return promise_rejects_dom(t, 'InvalidStateError', decoder.decode()); + }) + .then(_ => { + decoder.tracks[0].selected = true; + assert_equals(decoder.tracks.selectedIndex, 0); + assert_not_equals(decoder.tracks.selected, null); + return decoder.decode(); + }) + .then(result => { + assert_equals(result.image.displayWidth, 320); + assert_equals(result.image.displayHeight, 240); + }); +}, 'Test decode, decodeMetadata after no track selected.'); + +promise_test(t => { + var decoder = null; + + return fetch('four-colors-flip.avif') + .then(response => { + decoder = new ImageDecoder( + {data: response.body, type: 'image/avif', preferAnimation: false}); + return decoder.decodeMetadata(); + }) + .then(_ => { + assert_equals(decoder.tracks.length, 2); + assert_false(decoder.tracks[decoder.tracks.selectedIndex].animated) + assert_false(decoder.tracks.selectedTrack.animated); + assert_equals(decoder.tracks.selectedTrack.frameCount, 1); + assert_equals(decoder.tracks.selectedTrack.repetitionCount, 0); + return decoder.decode(); + }) + .then(result => { + assert_equals(result.image.displayWidth, 320); + assert_equals(result.image.displayHeight, 240); + + // Swap to the the other track. + let newIndex = (decoder.tracks.selectedIndex + 1) % 2; + decoder.tracks[newIndex].selected = true; + return decoder.decode() + }) + .then(result => { + assert_equals(result.image.displayWidth, 320); + assert_equals(result.image.displayHeight, 240); + + assert_equals(decoder.tracks.length, 2); + assert_true(decoder.tracks[decoder.tracks.selectedIndex].animated) + assert_true(decoder.tracks.selectedTrack.animated); + assert_equals(decoder.tracks.selectedTrack.frameCount, 7); + assert_equals(decoder.tracks.selectedTrack.repetitionCount, Infinity); + }); +}, 'Test track selection in multi track image.'); + class InfiniteGifSource { async load(repetitionCount) { let response = await fetch('four-colors-flip.gif'); @@ -141,21 +225,21 @@ let decoder = new ImageDecoder({data: stream, type: 'image/gif'}); return decoder.decodeMetadata() .then(_ => { - assert_equals(decoder.frameCount, 2); - assert_equals(decoder.repetitionCount, 5); + assert_equals(decoder.tracks.selectedTrack.frameCount, 2); + assert_equals(decoder.tracks.selectedTrack.repetitionCount, 5); source.addFrame(); return decoder.decode({frameIndex: 2}); }) .then(result => { - assert_equals(decoder.frameCount, 3); + assert_equals(decoder.tracks.selectedTrack.frameCount, 3); assert_equals(result.image.displayWidth, 320); assert_equals(result.image.displayHeight, 240); source.addFrame(); return decoder.decode({frameIndex: 3}); }) .then(result => { - assert_equals(decoder.frameCount, 4); + assert_equals(decoder.tracks.selectedTrack.frameCount, 4); assert_equals(result.image.displayWidth, 320); assert_equals(result.image.displayHeight, 240); @@ -166,26 +250,24 @@ }) .then(_ => { // Ensure we can still decode earlier frames. - assert_equals(decoder.frameCount, 4); + assert_equals(decoder.tracks.selectedTrack.frameCount, 4); return decoder.decode({frameIndex: 3}); }) .then(result => { - assert_equals(decoder.frameCount, 4); + assert_equals(decoder.tracks.selectedTrack.frameCount, 4); assert_equals(result.image.displayWidth, 320); assert_equals(result.image.displayHeight, 240); // Decode frame not yet available then close before it comes in. let p = decoder.decode({frameIndex: 5}); + let tracks = decoder.tracks; + let track = decoder.tracks.selectedTrack; decoder.close(); - assert_equals(decoder.frameCount, 0); - assert_equals(decoder.repetitionCount, 0); - assert_equals(decoder.type, ""); + assert_equals(decoder.type, ''); assert_equals(decoder.tracks.length, 0); - - assert_throws_dom('InvalidStateError', _ => { - decoder.selectTrack(1); - }); + assert_equals(tracks.length, 0); + track.selected = true; // Should do nothing. // Previous decode should be aborted. return promise_rejects_dom(t, 'AbortError', p); @@ -200,3 +282,20 @@ return promise_rejects_dom(t, 'InvalidStateError', decoder.decode()); }); }, 'Test ReadableStream of gif'); + +promise_test(async t => { + let source = new InfiniteGifSource(); + await source.load(5); + + let stream = new ReadableStream(source, {type: 'bytes'}); + let decoder = new ImageDecoder({data: stream, type: 'image/gif'}); + return decoder.decodeMetadata().then(_ => { + assert_equals(decoder.tracks.selectedTrack.frameCount, 2); + assert_equals(decoder.tracks.selectedTrack.repetitionCount, 5); + + // Decode frame not yet available then change tracks before it comes in. + let p = decoder.decode({frameIndex: 5}); + decoder.tracks.selectedTrack.selected = false; + return promise_rejects_dom(t, 'AbortError', p); + }); +}, 'Test ReadableStream aborts promises on track change');
diff --git a/third_party/blink/web_tests/platform/android/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001-expected.txt b/third_party/blink/web_tests/platform/android/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001-expected.txt deleted file mode 100644 index 231fddb2..0000000 --- a/third_party/blink/web_tests/platform/android/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584
diff --git a/third_party/blink/web_tests/platform/android/external/wpt/css/css-grid/grid-model/grid-support-display-001-expected.txt b/third_party/blink/web_tests/platform/android/external/wpt/css/css-grid/grid-model/grid-support-display-001-expected.txt deleted file mode 100644 index 231fddb2..0000000 --- a/third_party/blink/web_tests/platform/android/external/wpt/css/css-grid/grid-model/grid-support-display-001-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt deleted file mode 100644 index b8d04bb..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt +++ /dev/null
@@ -1,103 +0,0 @@ -This is a testharness.js-based test. -PASS .grid 1 -PASS .grid 2 -PASS .grid 3 -PASS .grid 4 -PASS .grid 5 -PASS .grid 6 -PASS .grid 7 -PASS .grid 8 -PASS .grid 9 -PASS .grid 10 -PASS .grid 11 -PASS .grid 12 -PASS .grid 13 -PASS .grid 14 -PASS .grid 15 -PASS .grid 16 -PASS .grid 17 -PASS .grid 18 -PASS .grid 19 -PASS .grid 20 -PASS .grid 21 -PASS .grid 22 -PASS .grid 23 -PASS .grid 24 -PASS .grid 25 -PASS .grid 26 -PASS .grid 27 -PASS .grid 28 -PASS .grid 29 -PASS .grid 30 -PASS .grid 31 -PASS .grid 32 -PASS .grid 33 -PASS .grid 34 -PASS .grid 35 -PASS .grid 36 -PASS .grid 37 -PASS .grid 38 -PASS .grid 39 -PASS .grid 40 -PASS .grid 41 -PASS .grid 42 -PASS .grid 43 -PASS .grid 44 -PASS .grid 45 -PASS .grid 46 -PASS .grid 47 -PASS .grid 48 -PASS .grid 49 -PASS .grid 50 -PASS .grid 51 -PASS .grid 52 -PASS .grid 53 -PASS .grid 54 -PASS .grid 55 -PASS .grid 56 -PASS .grid 57 -PASS .grid 58 -PASS .grid 59 -PASS .grid 60 -PASS .grid 61 -PASS .grid 62 -PASS .grid 63 -PASS .grid 64 -PASS .grid 65 -PASS .grid 66 -PASS .grid 67 -PASS .grid 68 -PASS .grid 69 -PASS .grid 70 -PASS .grid 71 -PASS .grid 72 -PASS .grid 73 -PASS .grid 74 -PASS .grid 75 -PASS .grid 76 -PASS .grid 77 -PASS .grid 78 -PASS .grid 79 -PASS .grid 80 -PASS .grid 81 -PASS .grid 82 -PASS .grid 83 -PASS .grid 84 -PASS .grid 85 -PASS .grid 86 -PASS .grid 87 -PASS .grid 88 -PASS .grid 89 -PASS .grid 90 -PASS .grid 91 -PASS .grid 92 -PASS .grid 93 -PASS .grid 94 -PASS .grid 95 -PASS .grid 96 -PASS .grid 97 -PASS .grid 98 -PASS .grid 99 -PASS .grid 100 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt deleted file mode 100644 index b8d04bb..0000000 --- a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt +++ /dev/null
@@ -1,103 +0,0 @@ -This is a testharness.js-based test. -PASS .grid 1 -PASS .grid 2 -PASS .grid 3 -PASS .grid 4 -PASS .grid 5 -PASS .grid 6 -PASS .grid 7 -PASS .grid 8 -PASS .grid 9 -PASS .grid 10 -PASS .grid 11 -PASS .grid 12 -PASS .grid 13 -PASS .grid 14 -PASS .grid 15 -PASS .grid 16 -PASS .grid 17 -PASS .grid 18 -PASS .grid 19 -PASS .grid 20 -PASS .grid 21 -PASS .grid 22 -PASS .grid 23 -PASS .grid 24 -PASS .grid 25 -PASS .grid 26 -PASS .grid 27 -PASS .grid 28 -PASS .grid 29 -PASS .grid 30 -PASS .grid 31 -PASS .grid 32 -PASS .grid 33 -PASS .grid 34 -PASS .grid 35 -PASS .grid 36 -PASS .grid 37 -PASS .grid 38 -PASS .grid 39 -PASS .grid 40 -PASS .grid 41 -PASS .grid 42 -PASS .grid 43 -PASS .grid 44 -PASS .grid 45 -PASS .grid 46 -PASS .grid 47 -PASS .grid 48 -PASS .grid 49 -PASS .grid 50 -PASS .grid 51 -PASS .grid 52 -PASS .grid 53 -PASS .grid 54 -PASS .grid 55 -PASS .grid 56 -PASS .grid 57 -PASS .grid 58 -PASS .grid 59 -PASS .grid 60 -PASS .grid 61 -PASS .grid 62 -PASS .grid 63 -PASS .grid 64 -PASS .grid 65 -PASS .grid 66 -PASS .grid 67 -PASS .grid 68 -PASS .grid 69 -PASS .grid 70 -PASS .grid 71 -PASS .grid 72 -PASS .grid 73 -PASS .grid 74 -PASS .grid 75 -PASS .grid 76 -PASS .grid 77 -PASS .grid 78 -PASS .grid 79 -PASS .grid 80 -PASS .grid 81 -PASS .grid 82 -PASS .grid 83 -PASS .grid 84 -PASS .grid 85 -PASS .grid 86 -PASS .grid 87 -PASS .grid 88 -PASS .grid 89 -PASS .grid 90 -PASS .grid 91 -PASS .grid 92 -PASS .grid 93 -PASS .grid 94 -PASS .grid 95 -PASS .grid 96 -PASS .grid 97 -PASS .grid 98 -PASS .grid 99 -PASS .grid 100 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt deleted file mode 100644 index b8d04bb..0000000 --- a/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-007-expected.txt +++ /dev/null
@@ -1,103 +0,0 @@ -This is a testharness.js-based test. -PASS .grid 1 -PASS .grid 2 -PASS .grid 3 -PASS .grid 4 -PASS .grid 5 -PASS .grid 6 -PASS .grid 7 -PASS .grid 8 -PASS .grid 9 -PASS .grid 10 -PASS .grid 11 -PASS .grid 12 -PASS .grid 13 -PASS .grid 14 -PASS .grid 15 -PASS .grid 16 -PASS .grid 17 -PASS .grid 18 -PASS .grid 19 -PASS .grid 20 -PASS .grid 21 -PASS .grid 22 -PASS .grid 23 -PASS .grid 24 -PASS .grid 25 -PASS .grid 26 -PASS .grid 27 -PASS .grid 28 -PASS .grid 29 -PASS .grid 30 -PASS .grid 31 -PASS .grid 32 -PASS .grid 33 -PASS .grid 34 -PASS .grid 35 -PASS .grid 36 -PASS .grid 37 -PASS .grid 38 -PASS .grid 39 -PASS .grid 40 -PASS .grid 41 -PASS .grid 42 -PASS .grid 43 -PASS .grid 44 -PASS .grid 45 -PASS .grid 46 -PASS .grid 47 -PASS .grid 48 -PASS .grid 49 -PASS .grid 50 -PASS .grid 51 -PASS .grid 52 -PASS .grid 53 -PASS .grid 54 -PASS .grid 55 -PASS .grid 56 -PASS .grid 57 -PASS .grid 58 -PASS .grid 59 -PASS .grid 60 -PASS .grid 61 -PASS .grid 62 -PASS .grid 63 -PASS .grid 64 -PASS .grid 65 -PASS .grid 66 -PASS .grid 67 -PASS .grid 68 -PASS .grid 69 -PASS .grid 70 -PASS .grid 71 -PASS .grid 72 -PASS .grid 73 -PASS .grid 74 -PASS .grid 75 -PASS .grid 76 -PASS .grid 77 -PASS .grid 78 -PASS .grid 79 -PASS .grid 80 -PASS .grid 81 -PASS .grid 82 -PASS .grid 83 -PASS .grid 84 -PASS .grid 85 -PASS .grid 86 -PASS .grid 87 -PASS .grid 88 -PASS .grid 89 -PASS .grid 90 -PASS .grid 91 -PASS .grid 92 -PASS .grid 93 -PASS .grid 94 -PASS .grid 95 -PASS .grid 96 -PASS .grid 97 -PASS .grid 98 -PASS .grid 99 -PASS .grid 100 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/layout-ng-grid/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent-expected.txt b/third_party/blink/web_tests/virtual/layout-ng-grid/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent-expected.txt deleted file mode 100644 index 973e755..0000000 --- a/third_party/blink/web_tests/virtual/layout-ng-grid/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent-expected.txt +++ /dev/null
@@ -1,31 +0,0 @@ -This is a testharness.js-based test. -FAIL Property grid-template-rows value 'masonry' assert_true: 'masonry' is a supported value for grid-template-rows. expected true got false -PASS Property grid-template-columns value 'none' -FAIL Property grid-template-columns value '20%' assert_equals: expected "60px" but got "20%" -PASS Property grid-template-columns value 'calc(-0.5em + 10px)' -PASS Property grid-template-columns value 'calc(0.5em + 10px)' -FAIL Property grid-template-columns value 'calc(30% + 40px)' assert_equals: expected "130px" but got "calc(30% + 40px)" -FAIL Property grid-template-columns value '5fr' assert_equals: expected "300px" but got "5fr" -FAIL Property grid-template-columns value 'min-content' assert_equals: expected "30px" but got "min-content" -FAIL Property grid-template-columns value 'max-content' assert_equals: expected "30px" but got "max-content" -FAIL Property grid-template-columns value 'auto' assert_equals: expected "300px" but got "auto" -FAIL Property grid-template-columns value 'minmax(10px, auto)' assert_equals: expected "300px" but got "minmax(10px, auto)" -FAIL Property grid-template-columns value 'minmax(20%, max-content)' assert_equals: expected "60px" but got "minmax(20%, max-content)" -FAIL Property grid-template-columns value 'minmax(min-content, calc(-0.5em + 10px))' assert_equals: expected "30px" but got "minmax(min-content, 0px)" -FAIL Property grid-template-columns value 'minmax(auto, 0)' assert_equals: expected "30px" but got "minmax(auto, 0px)" -FAIL Property grid-template-columns value 'fit-content(70px)' assert_equals: expected "30px" but got "fit-content(70px)" -FAIL Property grid-template-columns value 'fit-content(20%)' assert_equals: expected "30px" but got "fit-content(20%)" -FAIL Property grid-template-columns value 'fit-content(calc(-0.5em + 10px))' assert_equals: expected "30px" but got "fit-content(0px)" -PASS Property grid-template-columns value 'repeat(1, 10px)' -FAIL Property grid-template-columns value 'repeat(1, [one two] 20%)' assert_equals: expected "[one two] 60px" but got "[one two] 20%" -FAIL Property grid-template-columns value 'repeat(2, minmax(10px, auto))' assert_equals: expected "160px 140px" but got "minmax(10px, auto) minmax(10px, auto)" -FAIL Property grid-template-columns value 'repeat(2, fit-content(20%) [three four] 30px 40px [five six])' assert_equals: expected "30px [three four] 30px 40px [five six] 0px [three four] 30px 40px [five six]" but got "fit-content(20%) [three four] 30px 40px [five six] fit-content(20%) [three four] 30px 40px [five six]" -FAIL Property grid-template-columns value 'min-content repeat(5, minmax(10px, auto))' assert_equals: expected "30px 54px 54px 54px 54px 54px" but got "min-content minmax(10px, auto) minmax(10px, auto) minmax(10px, auto) minmax(10px, auto) minmax(10px, auto)" -FAIL Property grid-template-columns value '[] 150px [] 1fr []' assert_equals: expected "150px 150px" but got "150px 1fr" -FAIL Property grid-template-columns value 'repeat(auto-fill, 200px)' assert_equals: expected "200px" but got "repeat(auto-fill, 200px)" -FAIL Property grid-template-columns value 'repeat(auto-fit, [one] 20%)' assert_equals: expected "[one] 60px [one] 0px [one] 0px [one] 0px [one] 0px" but got "repeat(auto-fit, [one] 20%)" -FAIL Property grid-template-columns value 'repeat(auto-fill, minmax(100px, 5fr) [two])' assert_equals: expected "100px [two] 100px [two] 100px [two]" but got "repeat(auto-fill, minmax(100px, 5fr) [two])" -FAIL Property grid-template-columns value 'repeat(auto-fit, [three] minmax(max-content, 6em) [four])' assert_equals: expected "[three] 240px [four]" but got "repeat(auto-fit, [three] minmax(max-content, 240px) [four])" -FAIL Property grid-template-columns value '[one] repeat(2, minmax(50px, auto)) [two] 30px [three] repeat(auto-fill, 10px) 40px [four five] repeat(2, minmax(200px, auto)) [six]' assert_equals: expected "[one] 50px 50px [two] 30px [three] 10px 40px [four five] 200px 200px [six]" but got "[one] minmax(50px, auto) minmax(50px, auto) [two] 30px [three] repeat(auto-fill, 10px) 40px [four five] minmax(200px, auto) minmax(200px, auto) [six]" -Harness: the test ran to completion. -
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 521794c..4c8f0bd 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
@@ -763,8 +763,6 @@ [Worker] static method isTypeSupported [Worker] attribute @@toStringTag [Worker] getter complete -[Worker] getter frameCount -[Worker] getter repetitionCount [Worker] getter tracks [Worker] getter type [Worker] method close @@ -772,7 +770,21 @@ [Worker] method decode [Worker] method decodeMetadata [Worker] method reset -[Worker] method selectTrack +[Worker] interface ImageTrack +[Worker] attribute @@toStringTag +[Worker] getter animated +[Worker] getter frameCount +[Worker] getter repetitionCount +[Worker] getter selected +[Worker] method constructor +[Worker] setter selected +[Worker] interface ImageTrackList +[Worker] attribute @@toStringTag +[Worker] getter length +[Worker] getter selectedIndex +[Worker] getter selectedTrack +[Worker] method @@iterator +[Worker] method constructor [Worker] interface Lock [Worker] attribute @@toStringTag [Worker] getter mode
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 37ba4d0..1ab8551 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
@@ -7220,8 +7220,6 @@ static method isTypeSupported attribute @@toStringTag getter complete - getter frameCount - getter repetitionCount getter tracks getter type method close @@ -7229,7 +7227,21 @@ method decode method decodeMetadata method reset - method selectTrack +interface ImageTrack + attribute @@toStringTag + getter animated + getter frameCount + getter repetitionCount + getter selected + method constructor + setter selected +interface ImageTrackList + attribute @@toStringTag + getter length + getter selectedIndex + getter selectedTrack + method @@iterator + method constructor interface Ink attribute @@toStringTag method constructor
diff --git a/third_party/closure_compiler/README.chromium b/third_party/closure_compiler/README.chromium index a4d9ff8..a2038c6 100644 --- a/third_party/closure_compiler/README.chromium +++ b/third_party/closure_compiler/README.chromium
@@ -2,7 +2,7 @@ Short Name: closure-compiler URL: http://github.com/google/closure-compiler Version: 20210302.0.0 -Date: 2021/03/09 11:25 +Date: 2021/03/23 20:13 License: Apache 2.0 License File: LICENSE Security Critical: no
diff --git a/third_party/closure_compiler/chromium_patch.diff b/third_party/closure_compiler/chromium_patch.diff index ef86e8f..eba343e 100644 --- a/third_party/closure_compiler/chromium_patch.diff +++ b/third_party/closure_compiler/chromium_patch.diff
@@ -55,7 +55,7 @@ * Returns an object representing current load times. Note that the properties * on the object do not change and the function must be called again to get diff --git b/third_party/closure_compiler/externs/chrome_extensions.js a/third_party/closure_compiler/externs/chrome_extensions.js -index 276232d3f990..808f11f84084 100644 +index 41b2f5b485c7..7110aaf8f223 100644 --- b/third_party/closure_compiler/externs/chrome_extensions.js +++ a/third_party/closure_compiler/externs/chrome_extensions.js @@ -233,72 +233,6 @@ if (Math.random() < 1) { // always true but the compiler doesn't know that @@ -181,7 +181,159 @@ /** @type {string} */ -@@ -8528,642 +8505,6 @@ chrome.fileSystem.requestFileSystem = function(options, callback) {}; +@@ -4380,151 +4357,6 @@ chrome.idle.getAutoLockDelay = function(callback) {}; + chrome.idle.onStateChanged; + + +-/** +- * Chrome Text-to-Speech API. +- * @const +- * @see https://developer.chrome.com/extensions/tts.html +- */ +-chrome.tts = {}; +- +- +- +-/** +- * An event from the TTS engine to communicate the status of an utterance. +- * @constructor +- */ +-function TtsEvent() {} +- +- +-/** @type {string} */ +-TtsEvent.prototype.type; +- +- +-/** @type {number} */ +-TtsEvent.prototype.charIndex; +- +- +-/** @type {string} */ +-TtsEvent.prototype.errorMessage; +- +- +-/** +- * The speech options for the TTS engine. +- * @record +- * @see https://developer.chrome.com/apps/tts#type-TtsOptions +- */ +-function TtsOptions() {} +- +-/** @type {boolean|undefined} */ +-TtsOptions.prototype.enqueue; +- +-/** @type {string|undefined} */ +-TtsOptions.prototype.voiceName; +- +-/** @type {string|undefined} */ +-TtsOptions.prototype.extensionId; +- +-/** @type {string|undefined} */ +-TtsOptions.prototype.lang; +- +-/** @type {number|undefined} */ +-TtsOptions.prototype.rate; +- +-/** @type {number|undefined} */ +-TtsOptions.prototype.pitch; +- +-/** @type {number|undefined} */ +-TtsOptions.prototype.volume; +- +-/** @type {!Array<string>|undefined} */ +-TtsOptions.prototype.requiredEventTypes; +- +-/** @type {!Array<string>|undefined} */ +-TtsOptions.prototype.desiredEventTypes; +- +-/** @type {!function(!TtsEvent)|undefined} */ +-TtsOptions.prototype.onEvent; +- +- +-/** +- * A description of a voice available for speech synthesis. +- * @constructor +- */ +-function TtsVoice() {} +- +- +-/** @type {string} */ +-TtsVoice.prototype.voiceName; +- +- +-/** @type {string} */ +-TtsVoice.prototype.lang; +- +- +-/** @type {string} */ +-TtsVoice.prototype.gender; +- +- +-/** @type {string} */ +-TtsVoice.prototype.extensionId; +- +- +-/** @type {Array<string>} */ +-TtsVoice.prototype.eventTypes; +- +- +-/** +- * Gets an array of all available voices. +- * @param {function(Array<TtsVoice>)=} opt_callback An optional callback +- * function. +- * @return {undefined} +- */ +-chrome.tts.getVoices = function(opt_callback) {}; +- +- +-/** +- * Checks if the engine is currently speaking. +- * @param {function(boolean)=} opt_callback The callback function. +- * @return {undefined} +- */ +-chrome.tts.isSpeaking = function(opt_callback) {}; +- +- +-/** +- * Speaks text using a text-to-speech engine. +- * @param {string} utterance The text to speak, either plain text or a complete, +- * well-formed SSML document. Speech engines that do not support SSML will +- * strip away the tags and speak the text. The maximum length of the text is +- * 32,768 characters. +- * @param {TtsOptions=} options The speech options. +- * @param {function()=} callback Called right away, before speech finishes. +- * @return {undefined} +- */ +-chrome.tts.speak = function(utterance, options, callback) {}; +- +- +-/** +- * Stops any current speech. +- * @return {undefined} +- */ +-chrome.tts.stop = function() {}; +- +- +-/** +- * @const +- * @see https://developer.chrome.com/extensions/ttsEngine.html +- */ +-chrome.ttsEngine = {}; +- +- +-/** @type {!ChromeEvent} */ +-chrome.ttsEngine.onSpeak; +- +- +-/** @type {!ChromeEvent} */ +-chrome.ttsEngine.onStop; +- +- + /** + * @const + * @see https://developer.chrome.com/extensions/contentSettings.html +@@ -8474,642 +8306,6 @@ chrome.fileSystem.requestFileSystem = function(options, callback) {}; chrome.fileSystem.getVolumeList = function(callback) {};
diff --git a/third_party/closure_compiler/externs/chrome_extensions.js b/third_party/closure_compiler/externs/chrome_extensions.js index 0651ffa..7110aaf8 100644 --- a/third_party/closure_compiler/externs/chrome_extensions.js +++ b/third_party/closure_compiler/externs/chrome_extensions.js
@@ -4358,151 +4358,6 @@ /** - * Chrome Text-to-Speech API. - * @const - * @see https://developer.chrome.com/extensions/tts.html - */ -chrome.tts = {}; - - - -/** - * An event from the TTS engine to communicate the status of an utterance. - * @constructor - */ -function TtsEvent() {} - - -/** @type {string} */ -TtsEvent.prototype.type; - - -/** @type {number} */ -TtsEvent.prototype.charIndex; - - -/** @type {string} */ -TtsEvent.prototype.errorMessage; - - -/** - * The speech options for the TTS engine. - * @record - * @see https://developer.chrome.com/apps/tts#type-TtsOptions - */ -function TtsOptions() {} - -/** @type {boolean|undefined} */ -TtsOptions.prototype.enqueue; - -/** @type {string|undefined} */ -TtsOptions.prototype.voiceName; - -/** @type {string|undefined} */ -TtsOptions.prototype.extensionId; - -/** @type {string|undefined} */ -TtsOptions.prototype.lang; - -/** @type {number|undefined} */ -TtsOptions.prototype.rate; - -/** @type {number|undefined} */ -TtsOptions.prototype.pitch; - -/** @type {number|undefined} */ -TtsOptions.prototype.volume; - -/** @type {!Array<string>|undefined} */ -TtsOptions.prototype.requiredEventTypes; - -/** @type {!Array<string>|undefined} */ -TtsOptions.prototype.desiredEventTypes; - -/** @type {!function(!TtsEvent)|undefined} */ -TtsOptions.prototype.onEvent; - - -/** - * A description of a voice available for speech synthesis. - * @constructor - */ -function TtsVoice() {} - - -/** @type {string} */ -TtsVoice.prototype.voiceName; - - -/** @type {string} */ -TtsVoice.prototype.lang; - - -/** @type {string} */ -TtsVoice.prototype.gender; - - -/** @type {string} */ -TtsVoice.prototype.extensionId; - - -/** @type {Array<string>} */ -TtsVoice.prototype.eventTypes; - - -/** - * Gets an array of all available voices. - * @param {function(Array<TtsVoice>)=} opt_callback An optional callback - * function. - * @return {undefined} - */ -chrome.tts.getVoices = function(opt_callback) {}; - - -/** - * Checks if the engine is currently speaking. - * @param {function(boolean)=} opt_callback The callback function. - * @return {undefined} - */ -chrome.tts.isSpeaking = function(opt_callback) {}; - - -/** - * Speaks text using a text-to-speech engine. - * @param {string} utterance The text to speak, either plain text or a complete, - * well-formed SSML document. Speech engines that do not support SSML will - * strip away the tags and speak the text. The maximum length of the text is - * 32,768 characters. - * @param {TtsOptions=} options The speech options. - * @param {function()=} callback Called right away, before speech finishes. - * @return {undefined} - */ -chrome.tts.speak = function(utterance, options, callback) {}; - - -/** - * Stops any current speech. - * @return {undefined} - */ -chrome.tts.stop = function() {}; - - -/** - * @const - * @see https://developer.chrome.com/extensions/ttsEngine.html - */ -chrome.ttsEngine = {}; - - -/** @type {!ChromeEvent} */ -chrome.ttsEngine.onSpeak; - - -/** @type {!ChromeEvent} */ -chrome.ttsEngine.onStop; - - -/** * @const * @see https://developer.chrome.com/extensions/contentSettings.html */
diff --git a/third_party/closure_compiler/externs/language_settings_private.js b/third_party/closure_compiler/externs/language_settings_private.js index 80456c8..6389f871 100644 --- a/third_party/closure_compiler/externs/language_settings_private.js +++ b/third_party/closure_compiler/externs/language_settings_private.js
@@ -147,6 +147,12 @@ chrome.languageSettingsPrivate.getTranslateTargetLanguage = function(callback) {}; /** + * Sets the translate target language given a language code. + * @param {string} languageCode + */ +chrome.languageSettingsPrivate.setTranslateTargetLanguage = function(languageCode) {}; + +/** * Gets all supported input methods, including third-party IMEs. Chrome OS only. * @param {function(!chrome.languageSettingsPrivate.InputMethodLists): void} * callback
diff --git a/third_party/closure_compiler/interfaces/language_settings_private_interface.js b/third_party/closure_compiler/interfaces/language_settings_private_interface.js index 1a79ec8..f98cdeef 100644 --- a/third_party/closure_compiler/interfaces/language_settings_private_interface.js +++ b/third_party/closure_compiler/interfaces/language_settings_private_interface.js
@@ -90,6 +90,12 @@ getTranslateTargetLanguage: function(callback) {}, /** + * Sets the translate target language given a language code. + * @param {string} languageCode + */ + setTranslateTargetLanguage: function(languageCode) {}, + + /** * Gets all supported input methods, including third-party IMEs. Chrome OS * only. * @param {function(!chrome.languageSettingsPrivate.InputMethodLists):void}
diff --git a/tools/android/modularization/convenience/lookup_dep.py b/tools/android/modularization/convenience/lookup_dep.py new file mode 100755 index 0000000..5c6f3f9 --- /dev/null +++ b/tools/android/modularization/convenience/lookup_dep.py
@@ -0,0 +1,204 @@ +#!/usr/bin/env python3 +# 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. +r'''Finds which build target(s) contain a particular Java class. + +This is a utility script for finding out which build target dependency needs to +be added to import a given Java class. + +It is a best-effort script. + +Example: + +Find build target with class FooUtil: + tools/android/modularization/convenience/lookup_dep.py FooUtil +''' + +import argparse +import collections +import dataclasses +import json +import logging +import os +import pathlib +import subprocess +import sys +from typing import Dict, List + +_SRC_DIR = pathlib.Path(__file__).parents[4].resolve() +print(_SRC_DIR) + +sys.path.append(str(_SRC_DIR / 'build' / 'android')) +from pylib import constants + + +def main(): + arg_parser = argparse.ArgumentParser( + description='Finds which build target contains a particular Java class.') + + arg_parser.add_argument('-C', + '--output-directory', + help='Build output directory.') + arg_parser.add_argument('classes', + nargs='+', + help=f'Java classes to search for') + arg_parser.add_argument('-v', + '--verbose', + action='store_true', + help=f'Verbose logging.') + + arguments = arg_parser.parse_args() + + logging.basicConfig( + level=logging.DEBUG if arguments.verbose else logging.WARNING, + format='%(asctime)s.%(msecs)03d %(levelname).1s %(message)s', + datefmt='%H:%M:%S') + + if arguments.output_directory: + constants.SetOutputDirectory(arguments.output_directory) + constants.CheckOutputDirectory() + out_dir: str = constants.GetOutDirectory() + + index = ClassLookupIndex(pathlib.Path(out_dir)) + for class_name in arguments.classes: + class_entries = index.match(class_name) + if not class_entries: + print(f'Could not find build target for class "{class_name}"') + elif len(class_entries) == 1: + class_entry = class_entries[0] + print(f'Class {class_entry.full_class_name} found:') + print(f' "{class_entry.target}"') + else: + print(f'Multiple targets with classes that match "{class_name}":') + print() + for class_entry in class_entries: + print(f' "{class_entry.target}"') + print(f' contains {class_entry.full_class_name}') + print() + + +@dataclasses.dataclass(frozen=True) +class ClassEntry: + """An assignment of a Java class to a build target.""" + full_class_name: str + target: str + + +class ClassLookupIndex: + """A map from full Java class to its build targets. + + A class might be in multiple targets if it's bytecode rewritten.""" + + def __init__(self, build_output_dir: pathlib.Path): + self._build_output_dir = build_output_dir + self._class_index = self._index_root() + + def match(self, search_string: str) -> List[ClassEntry]: + """Get class/target entries where the class matches search_string""" + # Priority 1: Exact full matches + if search_string in self._class_index: + return self._entries_for(search_string) + + # Priority 2: Match full class name (any case), if it's a class name + matches = [] + lower_search_string = search_string.lower() + if '.' not in lower_search_string: + for full_class_name in self._class_index: + package_and_class = full_class_name.rsplit('.', 1) + if len(package_and_class) < 2: + continue + class_name = package_and_class[1] + class_lower = class_name.lower() + if class_lower == lower_search_string: + matches.extend(self._entries_for(full_class_name)) + if matches: + return matches + + # Priority 3: Match anything + for full_class_name in self._class_index: + if lower_search_string in full_class_name.lower(): + matches.extend(self._entries_for(full_class_name)) + + return matches + + def _entries_for(self, class_name) -> List[ClassEntry]: + return [ + ClassEntry(class_name, target) + for target in self._class_index.get(class_name) + ] + + def _index_root(self) -> Dict[str, List[str]]: + """Create the class to target index.""" + logging.debug('Running list_java_targets.py...') + list_java_targets_command = [ + 'build/android/list_java_targets.py', '--type=java_library', + '--gn-labels', '--build', '--print-build-config-paths', + f'--output-directory={self._build_output_dir}' + ] + list_java_targets_run = subprocess.run(list_java_targets_command, + cwd=_SRC_DIR, + capture_output=True, + text=True, + check=True) + logging.debug('... done.') + + # Parse output of list_java_targets.py with mapping of build_target to + # build_config + root_build_targets = list_java_targets_run.stdout.split('\n') + class_index = collections.defaultdict(list) + for target_line in root_build_targets: + # Skip empty lines + if not target_line: + continue + + target_line_parts = target_line.split(': ') + assert len(target_line_parts) == 2, target_line_parts + target, build_config_path = target_line_parts + + # Read the location of the java_sources_file from the build_config + with open(build_config_path) as build_config_contents: + build_config: Dict = json.load(build_config_contents) + deps_info = build_config['deps_info'] + sources_path = deps_info.get('java_sources_file') + if not sources_path: + # TODO(crbug.com/1108362): Handle targets that have no + # deps_info.sources_path but contain srcjars. + continue + + # Read the java_sources_file, indexing the classes found + with open(self._build_output_dir / sources_path) as sources_contents: + sources_lines = sources_contents + for source_line in sources_lines: + source_path = pathlib.Path(source_line.strip()) + java_class = self._parse_full_java_class(source_path) + if java_class: + class_index[java_class].append(target) + continue + + return class_index + + def _parse_full_java_class(self, source_path: pathlib.Path) -> str: + """Guess the fully qualified class name from the path to the source file.""" + if source_path.suffix != '.java': + logging.warning(f'"{source_path}" does not have the .java suffix') + return None + + directory_path: pathlib.Path = source_path.parent + package_list_reversed = [] + for part in reversed(directory_path.parts): + package_list_reversed.append(part) + if part in ('com', 'org'): + break + else: + logging.debug(f'File {source_path} not in a subdir of "org" or "com", ' + 'cannot detect package heuristically.') + return None + + package = '.'.join(reversed(package_list_reversed)) + class_name = source_path.stem + return f'{package}.{class_name}' + + +if __name__ == '__main__': + main()
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-expected.cc b/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-expected.cc index 1a089e30..0fcc784 100644 --- a/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-expected.cc +++ b/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-expected.cc
@@ -278,11 +278,11 @@ namespace implicit_constructors { // Based on //base/strings/string_piece_forward.h: -template <typename STRING_TYPE> +template <typename CharT> class BasicStringPiece; -typedef BasicStringPiece<std::string> StringPiece; +typedef BasicStringPiece<char> StringPiece; // Based on //base/strings/string_piece.h: -template <typename STRING_TYPE> +template <typename CharT> class BasicStringPiece { public: constexpr BasicStringPiece(const char* str) {} @@ -305,8 +305,7 @@ // error: no matching function for call to 'FunctionTakingBasicStringPiece' // note: candidate function not viable: no known conversion from // 'base::CheckedPtr<const char>' to 'templated_functions::StringPiece' (aka - // 'BasicStringPiece<basic_string<char, char_traits<char>, allocator<char>>>') - // for 1st argument + // 'BasicStringPiece<char>') for 1st argument FunctionTakingBasicStringPiece(my_struct.const_char_ptr.get()); FunctionTakingBasicStringPieceRef(my_struct.const_char_ptr.get());
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-original.cc b/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-original.cc index 122b3c4b..e84a461 100644 --- a/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-original.cc +++ b/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-original.cc
@@ -276,11 +276,11 @@ namespace implicit_constructors { // Based on //base/strings/string_piece_forward.h: -template <typename STRING_TYPE> +template <typename CharT> class BasicStringPiece; -typedef BasicStringPiece<std::string> StringPiece; +typedef BasicStringPiece<char> StringPiece; // Based on //base/strings/string_piece.h: -template <typename STRING_TYPE> +template <typename CharT> class BasicStringPiece { public: constexpr BasicStringPiece(const char* str) {} @@ -303,8 +303,7 @@ // error: no matching function for call to 'FunctionTakingBasicStringPiece' // note: candidate function not viable: no known conversion from // 'base::CheckedPtr<const char>' to 'templated_functions::StringPiece' (aka - // 'BasicStringPiece<basic_string<char, char_traits<char>, allocator<char>>>') - // for 1st argument + // 'BasicStringPiece<char>') for 1st argument FunctionTakingBasicStringPiece(my_struct.const_char_ptr); FunctionTakingBasicStringPieceRef(my_struct.const_char_ptr);
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 4923cc93..5b1503ee 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -296,7 +296,6 @@ 'Linux Builder (reclient)': 'gpu_tests_release_bot_reclient', 'Linux TSan Builder (goma cache silo)': 'tsan_disable_nacl_release_bot', 'Linux TSan Builder (reclient)': 'tsan_disable_nacl_release_bot_reclient', - 'Linux Viz': 'release_trybot', 'lacros-amd64-generic-rel-fyi': 'chromeos_amd64-generic_lacros_rel', 'linux-ash-chromium-builder-fyi-rel': 'chromeos_with_codecs_release_bot', @@ -309,6 +308,7 @@ 'Site Isolation Android': 'android_release_bot_minimal_symbols_arm64', 'TSAN Debug (reclient)': 'tsan_disable_nacl_debug_bot_reclient', 'TSAN Release (reclient)': 'tsan_disable_nacl_release_bot_reclient', + 'TSAN Release (runsc-exp) (reclient)': 'tsan_disable_nacl_release_bot_reclient', 'UBSan Release (reclient)': 'ubsan_release_bot_reclient', 'VR Linux': 'vr_release_bot', 'VR Linux (reclient)': 'vr_release_bot_reclient', @@ -794,6 +794,7 @@ 'android-pie-arm64-rel': 'android_release_trybot_arm64_webview_google_expectations', 'android-pie-arm64-wpt-rel-non-cq': 'android_release_trybot_arm64_webview_google', 'android-pie-x86-rel': 'android_release_trybot_x86_fastbuild_webview_google', + 'android-web-platform-pie-x86-fyi-rel': 'android_release_trybot_x86_fastbuild_webview_google', 'android-weblayer-pie-x86-rel-tests': 'android_release_trybot_minimal_symbols_x86_fastbuild_webview_google', 'android-weblayer-pie-x86-fyi-rel': 'android_release_trybot_x86_fastbuild_webview_google', 'android-weblayer-pie-x86-wpt-fyi-rel': 'android_release_trybot_x86_fastbuild_webview_google',
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 21f7e04a..b5dab90 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -252,6 +252,15 @@ "use_rbe": true } }, + "TSAN Release (runsc-exp) (reclient)": { + "gn_args": { + "enable_nacl": false, + "is_component_build": false, + "is_debug": false, + "is_tsan": true, + "use_rbe": true + } + }, "UBSan Release (reclient)": { "gn_args": { "is_component_build": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json index 89d4d7d9..1d380d12 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -389,6 +389,23 @@ "use_goma": true } }, + "android-web-platform-pie-x86-fyi-rel": { + "gn_args": { + "dcheck_always_on": true, + "disable_android_lint": true, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "strip_debug_info": true, + "symbol_level": 1, + "system_webview_package_name": "com.google.android.webview", + "target_cpu": "x86", + "target_os": "android", + "use_errorprone_java_compiler": false, + "use_goma": true + } + }, "android-weblayer-pie-x86-fyi-rel": { "gn_args": { "dcheck_always_on": true,
diff --git a/tools/metrics/histograms/README.md b/tools/metrics/histograms/README.md index f937962..2f5ca60 100644 --- a/tools/metrics/histograms/README.md +++ b/tools/metrics/histograms/README.md
@@ -607,9 +607,10 @@ ### Cleaning Up Histogram Entries -Do not delete histograms from histograms.xml. Instead, mark unused histograms as -obsolete and annotate them with the date or milestone in the `<obsolete>` tag -entry. +Do not delete histograms from histograms.xml files or move them to +obsolete_histograms.xml. Instead, mark unused histograms as obsolete and +annotate them with the date or milestone in the `<obsolete>` tag entry. They +will later get moved to obsolete_histograms.xml via tooling. If deprecating only some variants of a [patterned histogram](#Patterned-Histograms), mark each deprecated `<variant>`
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 44911864..52aa920 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -24018,6 +24018,7 @@ <int value="837" label="SerialAllowAllPortsForUrls"/> <int value="838" label="SerialAllowUsbDevicesForUrls"/> <int value="839" label="ForcedLanguages"/> + <int value="840" label="BrowserThemeColor"/> </enum> <enum name="EnterprisePolicyDeviceIdValidity"> @@ -26893,6 +26894,7 @@ label="LANGUAGESETTINGSPRIVATE_SETLANGUAGEALWAYSTRANSLATESTATE"/> <int value="1546" label="ACCESSIBILITY_PRIVATE_SHOWCONFIRMATIONDIALOG"/> <int value="1547" label="AUTOTESTPRIVATE_INSTALLBOREALIS"/> + <int value="1548" label="LANGUAGESETTINGSPRIVATE_SETTRANSLATETARGETLANGUAGE"/> </enum> <enum name="ExtensionIconState"> @@ -39533,7 +39535,7 @@ <int value="24" label="AUTO_SIGNIN_FIRST_RUN_INFOBAR_DELEGATE (Obsolete)"/> <int value="25" label="GENERATED_PASSWORD_SAVED_INFOBAR_DELEGATE_ANDROID"/> <int value="26" label="SAVE_PASSWORD_INFOBAR_DELEGATE_MOBILE"/> - <int value="27" label="PEPPER_BROKER_INFOBAR_DELEGATE"/> + <int value="27" label="PEPPER_BROKER_INFOBAR_DELEGATE (Obsolete)"/> <int value="28" label="PERMISSION_UPDATE_INFOBAR_DELEGATE_ANDROID"/> <int value="29" label="DURABLE_STORAGE_PERMISSION_INFOBAR_DELEGATE_ANDROID (Obsolete)"/> @@ -39613,8 +39615,8 @@ <int value="100" label="LITE_MODE_HTTPS_IMAGE_COMPRESSION_INFOBAR_ANDROID"/> <int value="101" label="SYSTEM_INFOBAR_DELEGATE_MAC (Obsolete)"/> <int value="102" label="EXPERIMENTAL_INFOBAR_DELEGATE_LACROS"/> - <int value="103" label="ROSETTA_REQUIRED_INFOBAR_DELEGATE"/> - <int value="104" label="WEBID_PERMISSION_INFOBAR_DELEGATE"/> + <int value="103" label="ROSETTA_REQUIRED_INFOBAR_DELEGATE (Obsolete)"/> + <int value="104" label="WEBID_PERMISSION_INFOBAR_DELEGATE (Obsolete)"/> <int value="105" label="AUTOFILL_OFFER_NOTIFICATION_INFOBAR_DELEGATE"/> <int value="106" label="AUTOFILL_ADDRESS_PROFILE_INFOBAR_DELEGATE_IOS"/> </enum> @@ -44617,6 +44619,7 @@ <int value="-1308102778" label="IPH_DesktopSnoozeFeature:disabled"/> <int value="-1304957199" label="OfflinePagesShowAlternateDinoPage:enabled"/> <int value="-1304758527" label="SyncSendTabToSelf:disabled"/> + <int value="-1304401930" label="CSSContainerQueries:enabled"/> <int value="-1302904242" label="enable-navigation-tracing"/> <int value="-1302859198" label="enable-stylus-virtual-keyboard:disabled"/> <int value="-1301804101" @@ -45127,6 +45130,7 @@ <int value="-864205629" label="enable-offline-load-stale-cache"/> <int value="-863581676" label="BluetoothFixA2dpPacketSize:disabled"/> <int value="-861678473" label="disable-offer-upload-credit-cards"/> + <int value="-861524874" label="AutofillParseMerchantPromoCodeFields:enabled"/> <int value="-861343291" label="ChromeHome:disabled"/> <int value="-860578793" label="TabGridLayoutAndroid:disabled"/> <int value="-860534647" label="SiteDetails:enabled"/> @@ -45729,6 +45733,8 @@ <int value="-300542825" label="ChromeShareQRCode:disabled"/> <int value="-300018686" label="disable-cloud-import"/> <int value="-299841473" label="top-document-isolation:enabled"/> + <int value="-298629214" + label="AutofillParseMerchantPromoCodeFields:disabled"/> <int value="-298458993" label="SystemNotifications:enabled"/> <int value="-297716805" label="CrossOriginMediaPlaybackRequiresUserGesture:disabled"/> @@ -47851,6 +47857,7 @@ label="AutofillAlwaysReturnCloudTokenizedCard:enabled"/> <int value="1634897915" label="password-import-export:enabled"/> <int value="1634980726" label="VrShellExperimentalRendering:disabled"/> + <int value="1635695770" label="CSSContainerQueries:disabled"/> <int value="1635986352" label="ContextMenuSearchWithGoogleLens:enabled"/> <int value="1636721063" label="AutofillLocalCardMigrationShowFeedback:enabled"/> @@ -61043,6 +61050,15 @@ <int value="14" label="Show notification access setup response"/> </enum> +<enum name="PhoneHubNotificationAccessSetupStatus"> + <int value="1" label="Connecting to phone"/> + <int value="2" label="Timed out connecting to phone"/> + <int value="3" label="Disconnected from phone before setup complete"/> + <int value="4" label="Sent message to phone; awaiting response"/> + <int value="5" label="Completed successfully"/> + <int value="6" label="Phone is prohibited from granting access"/> +</enum> + <enum name="PhoneHubNotificationInteraction"> <int value="0" label="User sent an inline reply from notification"/> <int value="1" label="User dismissed notification"/>
diff --git a/tools/metrics/histograms/histograms_xml/password/histograms.xml b/tools/metrics/histograms/histograms_xml/password/histograms.xml index f28b466..18fc8b1 100644 --- a/tools/metrics/histograms/histograms_xml/password/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/password/histograms.xml
@@ -1969,27 +1969,27 @@ </histogram> <histogram name="PasswordManager.RequirementsSpecFetcher.HttpResponseCode" - enum="HttpResponseCode" expires_after="2021-04-04"> + enum="HttpResponseCode" expires_after="M95"> + <owner>kazinova@google.com</owner> <owner>battre@chromium.org</owner> - <owner>jdoerrie@chromium.org</owner> <summary> HTTP response code of fetching a password requirements file. </summary> </histogram> <histogram name="PasswordManager.RequirementsSpecFetcher.NetErrorCode" - enum="NetErrorCodes" expires_after="2021-08-09"> + enum="NetErrorCodes" expires_after="M95"> + <owner>kazinova@google.com</owner> <owner>battre@chromium.org</owner> - <owner>jdoerrie@chromium.org</owner> <summary> Network error code of fetching a password requirements file. </summary> </histogram> <histogram name="PasswordManager.RequirementsSpecFetcher.NetworkDuration" - units="ms" expires_after="2021-04-04"> + units="ms" expires_after="M95"> + <owner>kazinova@google.com</owner> <owner>battre@chromium.org</owner> - <owner>jdoerrie@chromium.org</owner> <summary> Time until the lookup for a password requirements file completed (or was aborted). @@ -1997,9 +1997,9 @@ </histogram> <histogram name="PasswordManager.RequirementsSpecFetcher.Result" - enum="PasswordRequirementsFetcherResult" expires_after="2021-04-04"> + enum="PasswordRequirementsFetcherResult" expires_after="M95"> + <owner>kazinova@google.com</owner> <owner>battre@chromium.org</owner> - <owner>jdoerrie@chromium.org</owner> <summary> Result of fetching requirements for password during password generation. </summary>
diff --git a/tools/metrics/histograms/histograms_xml/phonehub/histograms.xml b/tools/metrics/histograms/histograms_xml/phonehub/histograms.xml index 8e25bdbd..12bd87c 100644 --- a/tools/metrics/histograms/histograms_xml/phonehub/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/phonehub/histograms.xml
@@ -133,6 +133,37 @@ </token> </histogram> +<histogram name="PhoneHub.NotificationAccessSetup.SuccessfulSetupDuration" + units="ms" expires_after="M98"> + <owner>nohle@chromium.org</owner> + <owner>better-together-dev@google.com</owner> + <summary> + Records the time it takes for the user to successfully go through the + Chromebook UI that guides them through granting Phone Hub notifications + access on their phone. Emitted once at the end of a successful setup flow. + The user should only need to go through the flow once successfully for each + phone they pair to. + </summary> +</histogram> + +<histogram name="PhoneHub.NotificationAccessSetup.{AllStatusesOrLastStatus}" + enum="PhoneHubNotificationAccessSetupStatus" expires_after="M98"> + <owner>nohle@chromium.org</owner> + <owner>better-together-dev@google.com</owner> + <summary> + Records {AllStatusesOrLastStatus} the Chromebook UI that guides them through + granting Phone Hub notifications access on their phone. Emitted each time + the user goes through the notification access setup flow. The user should + only need to go through the flow once successfully for each phone they pair + to. + </summary> + <token key="AllStatusesOrLastStatus"> + <variant name="AllStatuses" summary="each step the user sees in"/> + <variant name="LastStatus" + summary="the last state the user experiences in"/> + </token> +</histogram> + <histogram name="PhoneHub.NotificationCount" units="notifications" expires_after="2021-10-31"> <owner>tengs@chromium.org</owner>
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py index 46224cd..1c81adb 100644 --- a/tools/perf/core/bot_platforms.py +++ b/tools/perf/core/bot_platforms.py
@@ -366,6 +366,7 @@ _WIN_10_AMD_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('kraken'), _GetBenchmarkConfig('octane'), + _GetBenchmarkConfig('system_health.common_desktop'), ]) _WIN_7_BENCHMARK_CONFIGS = PerfSuite([ 'loading.desktop',
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 05258a32..2e6b97a 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/win/91b4f68052b4d97bd4c803605b7f9577be2f0410/trace_processor_shell.exe" }, "mac": { - "hash": "7fcbef4941ad214bba1ac4fa520e8b9c7734772c", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/5c32bc92b27666942869e222783eed71b08147fb/trace_processor_shell" + "hash": "adadc8e1518cdebac9360e9653d7df0cf9fb0e0d", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/91b4f68052b4d97bd4c803605b7f9577be2f0410/trace_processor_shell" }, "linux": { "hash": "61904a302a04bc406a1ce09d34c56215f50063bb", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/91b4f68052b4d97bd4c803605b7f9577be2f0410/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/2fde995f9d7c1014e35dcae0afe403bb9d1eca7b/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/core/shard_maps/win-10_amd-perf_map.json b/tools/perf/core/shard_maps/win-10_amd-perf_map.json index 5b4f4150..03b2f04 100644 --- a/tools/perf/core/shard_maps/win-10_amd-perf_map.json +++ b/tools/perf/core/shard_maps/win-10_amd-perf_map.json
@@ -3,23 +3,31 @@ "benchmarks": { "kraken": { "abridged": false + }, + "octane": { + "abridged": false + }, + "system_health.common_desktop": { + "end": 39, + "abridged": false } } }, "1": { "benchmarks": { - "octane": { + "system_health.common_desktop": { + "begin": 39, "abridged": false } } }, "extra_infos": { - "num_stories": 2, - "predicted_min_shard_time": 10, + "num_stories": 82, + "predicted_min_shard_time": 410, "predicted_min_shard_index": 0, - "predicted_max_shard_time": 10, + "predicted_max_shard_time": 410, "predicted_max_shard_index": 0, - "shard #0": 10, - "shard #1": 10 + "shard #0": 410, + "shard #1": 410 } } \ No newline at end of file
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 20ccb4a..9f26571 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -311,6 +311,7 @@ crbug.com/1113921 [ android-go ] system_health.common_mobile/load:tools:dropbox:2019 [ Skip ] crbug.com/1139057 [ mobile ] system_health.common_mobile/browse:social:facebook:2019 [ Skip ] crbug.com/1154719 [ android-go ] system_health.common_mobile/browse:chrome:omnibox:2019 [ Skip ] +crbug.com/1192851 [ android ] system_health.common_mobile/browse:news:businessinsider:2021 [ Skip ] # Benchmark: system_health.memory_desktop crbug.com/649392 system_health.memory_desktop/play:media:google_play_music [ Skip ] @@ -401,6 +402,7 @@ crbug.com/1113921 [ android-go ] system_health.memory_mobile/load:tools:dropbox:2019 [ Skip ] crbug.com/1139057 [ mobile ] system_health.memory_mobile/browse:social:facebook:2019 [ Skip ] crbug.com/1154719 [ android-go ] system_health.memory_mobile/browse:chrome:omnibox:2019 [ Skip ] +crbug.com/1192851 [ android ] system_health.memory_mobile/browse:news:businessinsider:2021 [ Skip ] # Benchmark: system_health.pcscan crbug.com/v8/11180 [ android ] system_health.pcscan/browse:news:cnn:2021 [ Skip ] @@ -460,6 +462,7 @@ crbug.com/1139057 [ mobile ] v8.browsing_mobile/browse:social:facebook:2019 [ Skip ] crbug.com/1143740 [ android-pixel-2 android-webview ] v8.browsing_mobile/browse:media:imgur:2019 [ Skip ] crbug.com/1154719 [ android-go ] v8.browsing_mobile/browse:chrome:omnibox:2019 [ Skip ] +crbug.com/1192851 [ android ] v8.browsing_mobile/browse:news:businessinsider:2021 [ Skip ] # Benchmark: v8.browsing_mobile-future crbug.com/1036141 [ android-webview ] v8.browsing_mobile-future/browse:shopping:lazada:2019 [ Skip ]
diff --git a/tools/typescript/DIR_METADATA b/tools/typescript/DIR_METADATA new file mode 100644 index 0000000..8325efa --- /dev/null +++ b/tools/typescript/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>WebUI" +}
diff --git a/tools/typescript/OWNERS b/tools/typescript/OWNERS new file mode 100644 index 0000000..137a0709 --- /dev/null +++ b/tools/typescript/OWNERS
@@ -0,0 +1,2 @@ +dpapad@chromium.org +rbpotter@chromium.org
diff --git a/tools/typescript/PRESUBMIT.py b/tools/typescript/PRESUBMIT.py new file mode 100644 index 0000000..8dc19eb --- /dev/null +++ b/tools/typescript/PRESUBMIT.py
@@ -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. +"""Presubmit script for files in tools/typescript/ + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + + +def RunTypescriptTests(input_api, output_api): + presubmit_path = input_api.PresubmitLocalPath() + sources = ['ts_library_test.py'] + tests = [input_api.os_path.join(presubmit_path, s) for s in sources] + return input_api.canned_checks.RunUnitTests(input_api, output_api, tests) + + +def _CheckChangeOnUploadOrCommit(input_api, output_api): + results = [] + affected = input_api.AffectedFiles() + + sources = set(['ts_library.py', 'ts_library.gni', 'tsconfig_base.json']) + affected_files = [input_api.os_path.basename(f.LocalPath()) for f in affected] + if sources.intersection(set(affected_files)): + results += RunTypescriptTests(input_api, output_api) + + return results + + +def CheckChangeOnUpload(input_api, output_api): + return _CheckChangeOnUploadOrCommit(input_api, output_api) + + +def CheckChangeOnCommit(input_api, output_api): + return _CheckChangeOnUploadOrCommit(input_api, output_api)
diff --git a/tools/typescript/tests/project1/errors.ts b/tools/typescript/tests/project1/errors.ts new file mode 100644 index 0000000..7b4f6999 --- /dev/null +++ b/tools/typescript/tests/project1/errors.ts
@@ -0,0 +1,7 @@ +// 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. + +export function foo(): string { + return 17; +}
diff --git a/tools/typescript/tests/project1/foo.ts b/tools/typescript/tests/project1/foo.ts new file mode 100644 index 0000000..440ef4b --- /dev/null +++ b/tools/typescript/tests/project1/foo.ts
@@ -0,0 +1,11 @@ +// 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. + +export function foo(): string { + return 'foo'; +} + +export function num(): number { + return 17; +}
diff --git a/tools/typescript/tests/project2/bar.ts b/tools/typescript/tests/project2/bar.ts new file mode 100644 index 0000000..f961979 --- /dev/null +++ b/tools/typescript/tests/project2/bar.ts
@@ -0,0 +1,13 @@ +// 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 {foo} from '../project1/foo.js'; +import {num} from 'chrome://some-other-source/foo.js'; + +function doNothing(): void { + console.log(foo()); + console.log(num()); +} + +doNothing();
diff --git a/tools/typescript/ts_library.gni b/tools/typescript/ts_library.gni new file mode 100644 index 0000000..7938a324 --- /dev/null +++ b/tools/typescript/ts_library.gni
@@ -0,0 +1,67 @@ +# 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. + +template("ts_library") { + action(target_name) { + script = "//tools/typescript/ts_library.py" + + forward_variables_from(invoker, + [ + "deps", + "extra_deps", + "sources", + ]) + + inputs = [ "//tools/typescript/tsconfig_base.json" ] + outputs = [ + "$target_gen_dir/tsconfig.json", + "$target_gen_dir/tsconfig.manifest", + "$target_gen_dir/tsconfig.tsbuildinfo", + ] + foreach(_source, sources) { + _filename = + get_path_info(_source, "dir") + "/" + get_path_info(_source, "name") + outputs += [ + "$target_gen_dir/$_filename.js", + "$target_gen_dir/$_filename.d.ts", + ] + } + + root_dir = "." + if (defined(invoker.root_dir)) { + root_dir = invoker.root_dir + } + + args = [ + "--root_dir", + rebase_path(root_dir, root_build_dir), + "--gen_dir", + rebase_path(target_gen_dir, root_build_dir), + "--sources", + ] + sources + + if (defined(deps)) { + args += [ "--deps" ] + foreach(dep, deps) { + args += + [ rebase_path(get_label_info(dep, "dir"), ".") + "/tsconfig.json" ] + } + } + + if (defined(extra_deps)) { + if (!defined(deps)) { + deps = [] + } + deps += extra_deps + } + + path_mappings = + [ "chrome://resources/*|" + + rebase_path("$root_gen_dir/ui/webui/resources/*", target_gen_dir) ] + args += [ "--path_mappings" ] + path_mappings + if (defined(invoker.path_mappings)) { + args += invoker.path_mappings + } + } +}
diff --git a/tools/typescript/ts_library.py b/tools/typescript/ts_library.py new file mode 100644 index 0000000..14a1b7c5 --- /dev/null +++ b/tools/typescript/ts_library.py
@@ -0,0 +1,74 @@ +# 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 argparse +import json +import os +import re +import sys + +_CWD = os.getcwd() +_HERE_DIR = os.path.dirname(__file__) +_SRC_DIR = os.path.normpath(os.path.join(_HERE_DIR, '..', '..')) + +sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'node')) +import node +import node_modules + + +def _write_tsconfig_json(gen_dir, tsconfig): + if not os.path.exists(gen_dir): + os.makedirs(gen_dir) + + with open(os.path.join(gen_dir, 'tsconfig.json'), 'w') as generated_tsconfig: + json.dump(tsconfig, generated_tsconfig, indent=2) + return + + +def main(argv): + parser = argparse.ArgumentParser() + parser.add_argument('--deps', nargs='*') + parser.add_argument('--gen_dir', required=True) + parser.add_argument('--path_mappings', nargs='*') + parser.add_argument('--root_dir', required=True) + parser.add_argument('--sources', nargs='*', required=True) + args = parser.parse_args(argv) + + root_dir = os.path.relpath(args.root_dir, args.gen_dir) + sources = [os.path.join(root_dir, f) for f in args.sources] + + with open(os.path.join(_HERE_DIR, 'tsconfig_base.json')) as root_tsconfig: + tsconfig = json.loads(root_tsconfig.read()) + + tsconfig['files'] = sources + tsconfig['compilerOptions']['rootDir'] = root_dir + + # Handle custom path mappings, for example chrome://resources/ URLs. + if args.path_mappings is not None: + path_mappings = {} + for m in args.path_mappings: + mapping = m.split('|') + path_mappings[mapping[0]] = [os.path.join('./', mapping[1])] + tsconfig['compilerOptions']['paths'] = path_mappings + + if args.deps is not None: + tsconfig['references'] = [{'path': dep} for dep in args.deps] + + _write_tsconfig_json(args.gen_dir, tsconfig) + + node.RunNode([ + node_modules.PathToTypescript(), '--project', + os.path.join(args.gen_dir, 'tsconfig.json') + ]) + + with open(os.path.join(args.gen_dir, 'tsconfig.manifest'), 'w') \ + as manifest_file: + manifest_data = {} + manifest_data['base_dir'] = args.gen_dir + manifest_data['files'] = [re.sub(r'\.ts$', '.js', f) for f in args.sources] + json.dump(manifest_data, manifest_file) + + +if __name__ == '__main__': + main(sys.argv[1:])
diff --git a/tools/typescript/ts_library_test.py b/tools/typescript/ts_library_test.py new file mode 100755 index 0000000..c93847d --- /dev/null +++ b/tools/typescript/ts_library_test.py
@@ -0,0 +1,100 @@ +#!/usr/bin/env python +# 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 ts_library +import os +import shutil +import tempfile +import unittest + +_HERE_DIR = os.path.dirname(__file__) + + +class TsLibraryTest(unittest.TestCase): + def setUp(self): + self._out_folder = None + self._additional_flags = [] + + def tearDown(self): + if self._out_folder: + shutil.rmtree(self._out_folder) + + def _build_project1(self): + gen_dir = os.path.join(self._out_folder, 'project1') + ts_library.main([ + '--root_dir', + os.path.join(_HERE_DIR, 'tests', 'project1'), + '--gen_dir', + gen_dir, + '--sources', + 'foo.ts', + ]) + return gen_dir + + def _assert_project1_output(self, gen_dir): + os.path.exists(os.path.join(gen_dir, 'foo.d.ts')) + os.path.exists(os.path.join(gen_dir, 'foo.js')) + os.path.exists(os.path.join(gen_dir, 'tsconfig.json')) + os.path.exists(os.path.join(gen_dir, 'tsconfig.manifest')) + os.path.exists(os.path.join(gen_dir, 'tsconfig.tsbuildinfo')) + + # Builds project2 which depends on files from project1, both via relative + # URLs, as well as via absolute chrome:// URLs. + def _build_project2(self, project1_gen_dir): + gen_dir = os.path.join(self._out_folder, 'project2') + project1_gen_dir = os.path.relpath(project1_gen_dir, gen_dir) + + ts_library.main([ + '--root_dir', + os.path.join(_HERE_DIR, 'tests', 'project2'), + '--gen_dir', + gen_dir, + '--sources', + 'bar.ts', + '--deps', + os.path.join(project1_gen_dir, 'tsconfig.json'), + '--path_mappings', + 'chrome://some-other-source/*|' + os.path.join(project1_gen_dir, '*'), + ]) + return gen_dir + + def _assert_project2_output(self, gen_dir): + os.path.exists(os.path.join(gen_dir, 'bar.d.ts')) + os.path.exists(os.path.join(gen_dir, 'bar.js')) + os.path.exists(os.path.join(gen_dir, 'tsconfig.json')) + os.path.exists(os.path.join(gen_dir, 'tsconfig.manifest')) + os.path.exists(os.path.join(gen_dir, 'tsconfig.tsbuildinfo')) + + # Test success case where both project1 and project2 are compiled successfully + # and no errors are thrown. + def testSuccess(self): + self._out_folder = tempfile.mkdtemp(dir=_HERE_DIR) + project1_gen_dir = self._build_project1() + self._assert_project1_output(project1_gen_dir) + project2_gen_dir = self._build_project2(project1_gen_dir) + self._assert_project2_output(project2_gen_dir) + + # Test error case where a type violation exists, ensure that an error is + # thrown. + def testError(self): + self._out_folder = tempfile.mkdtemp(dir=_HERE_DIR) + try: + ts_library.main([ + '--root_dir', + os.path.join(_HERE_DIR, 'tests', 'project1'), + '--gen_dir', + os.path.join(self._out_folder, 'project1'), + '--sources', + 'errors.ts', + ]) + except RuntimeError as err: + self.assertTrue('Type \'number\' is not assignable to type \'string\'' \ + in err.message) + else: + self.fail('Failed to detect type error') + + +if __name__ == '__main__': + unittest.main()
diff --git a/tools/typescript/tsconfig_base.json b/tools/typescript/tsconfig_base.json new file mode 100644 index 0000000..94079dc --- /dev/null +++ b/tools/typescript/tsconfig_base.json
@@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "module": "ESNext", + "target": "ESNext", + "outDir": "./", + + "noEmitOnError": true, + "pretty": true, + + "composite": true, + "declaration": true, + "tsBuildInfoFile": "tsconfig.tsbuildinfo", + + "alwaysStrict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "strictBindCallApply": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "strict": true + } +}
diff --git a/ui/android/java/src/org/chromium/ui/base/Clipboard.java b/ui/android/java/src/org/chromium/ui/base/Clipboard.java index 3fde69b..ae29feff 100644 --- a/ui/android/java/src/org/chromium/ui/base/Clipboard.java +++ b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
@@ -26,6 +26,7 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.BuildInfo; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.StrictModeContext; @@ -34,6 +35,7 @@ import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; import org.chromium.base.compat.ApiHelperForO; +import org.chromium.base.compat.ApiHelperForS; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.task.AsyncTask; import org.chromium.ui.R; @@ -268,7 +270,8 @@ * @param text Plain-text representation of the HTML content. */ @CalledByNative - private void setHTMLText(final String html, final String text) { + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + void setHTMLText(final String html, final String text) { setPrimaryClipNoException(ClipData.newHtmlText("html", text, html)); } @@ -328,7 +331,8 @@ setPrimaryClipNoException(ClipData.newPlainText(null, null)); } - private boolean setPrimaryClipNoException(ClipData clip) { + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + boolean setPrimaryClipNoException(ClipData clip) { final String manufacturer = Build.MANUFACTURER.toLowerCase(Locale.US); // See crbug.com/1123727, there are OEM devices having strict mode violations in their // Android framework code. Disabling strict mode for non-google devices. @@ -499,6 +503,64 @@ return oldManager; } + /** + * Check if the system clipboard has content to be pasted. + * @return True if the system clipboard contains anything, otherwise, return false. + */ + public boolean canPaste() { + return mClipboardManager.hasPrimaryClip(); + } + + /** + * Check if need to show "paste as plain text" option. + * Don't show "paste as plain text" when "paste" and "paste as plain text" would do exactly the + * same. + * @return True if the system clipboard contains a styled text, or html text. + */ + @VisibleForTesting + public boolean canPasteAsPlainText() { + ClipDescription description = mClipboardManager.getPrimaryClipDescription(); + if (description == null) return false; + + boolean isPlainType = description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN); + // On Android, Spanned could be copied to Clipboard as plain_text MIME type, but in some + // cases, Spanned could have text format, we need to show "paste as plain text" when + // that happens. + return (isPlainType && hasStyledText(description)) + || description.hasMimeType(ClipDescription.MIMETYPE_TEXT_HTML); + } + + /** + * Check Whether the ClipDescription has stypled text. + * @param description The {@link ClipDescription} to check if it has stytled text. + * @return True if the system clipboard contain a styled text, otherwise, false. + */ + private boolean hasStyledText(ClipDescription description) { + if (BuildInfo.isAtLeastS()) { + return ApiHelperForS.isStyleText(description); + } else { + return hasStyledTextOnPreS(); + } + } + + private boolean hasStyledTextOnPreS() { + CharSequence text; + try { + // getPrimaryClip() has been observed to throw unexpected exceptions for some devices + // (see crbug.com/654802 and b/31501780) + text = mClipboardManager.getPrimaryClip().getItemAt(0).getText(); + } catch (Exception e) { + return false; + } + + if (text instanceof Spanned) { + Spanned spanned = (Spanned) text; + return hasStyleSpan(spanned); + } + + return false; + } + @NativeMethods interface Natives { void onPrimaryClipChanged(long nativeClipboardAndroid, Clipboard caller);
diff --git a/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java b/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java index 4c5e153..1359371 100644 --- a/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java +++ b/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java
@@ -7,6 +7,9 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.BackgroundColorSpan; import androidx.test.filters.SmallTest; @@ -90,4 +93,36 @@ clipboardManager.removePrimaryClipChangedListener(clipboardChangedListener); }); } + + @Test + @SmallTest + public void testPasteAsPlainTextForNormalText() { + TestThreadUtils.runOnUiThreadBlocking(() -> { + Clipboard.getInstance().setText("SampleTextToCopy"); + Assert.assertFalse(Clipboard.getInstance().canPasteAsPlainText()); + }); + } + + @Test + @SmallTest + public void testPasteAsPlainTextForStyledText() { + SpannableString spanString = new SpannableString("SpannableString"); + spanString.setSpan(new BackgroundColorSpan(0), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + ClipData clipData = + ClipData.newPlainText("text", spanString.subSequence(0, spanString.length() - 1)); + TestThreadUtils.runOnUiThreadBlocking(() -> { + Clipboard.getInstance().setPrimaryClipNoException(clipData); + Assert.assertTrue(Clipboard.getInstance().canPasteAsPlainText()); + }); + } + + @Test + @SmallTest + public void testPastePopupPasteAsPlainTextForHtmlText() { + TestThreadUtils.runOnUiThreadBlocking(() -> { + Clipboard.getInstance().setHTMLText( + "<span style=\"color: red;\">HTMLTextToCopy</span>", "HTMLTextToCopy"); + Assert.assertTrue(Clipboard.getInstance().canPasteAsPlainText()); + }); + } }
diff --git a/ui/base/OWNERS b/ui/base/OWNERS index 01f524d6..636b5c7 100644 --- a/ui/base/OWNERS +++ b/ui/base/OWNERS
@@ -1,3 +1,5 @@ +pbos@chromium.org + per-file template_expressions*=dpapad@chromium.org per-file template_expressions*=michaelpg@chromium.org per-file template_expressions*=rbpotter@chromium.org
diff --git a/ui/base/ime/fuchsia/BUILD.gn b/ui/base/ime/fuchsia/BUILD.gn index 0486505..1b98ae1 100644 --- a/ui/base/ime/fuchsia/BUILD.gn +++ b/ui/base/ime/fuchsia/BUILD.gn
@@ -19,6 +19,7 @@ defines = [ "IS_UI_BASE_IME_FUCHSIA_IMPL" ] public_deps = [ + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.input.virtualkeyboard", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.input3", "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
diff --git a/ui/base/ime/fuchsia/input_method_fuchsia.cc b/ui/base/ime/fuchsia/input_method_fuchsia.cc index 5b6b97d..aaa5a1e 100644 --- a/ui/base/ime/fuchsia/input_method_fuchsia.cc +++ b/ui/base/ime/fuchsia/input_method_fuchsia.cc
@@ -20,12 +20,7 @@ InputMethodFuchsia::InputMethodFuchsia(internal::InputMethodDelegate* delegate, fuchsia::ui::views::ViewRef view_ref) : InputMethodBase(delegate), - event_converter_(this), - ime_client_binding_(this), - ime_service_(base::ComponentContextForProcess() - ->svc() - ->Connect<fuchsia::ui::input::ImeService>()), - virtual_keyboard_controller_(ime_service_.get()) {} + virtual_keyboard_controller_(std::move(view_ref), this) {} InputMethodFuchsia::~InputMethodFuchsia() {} @@ -33,11 +28,6 @@ return &virtual_keyboard_controller_; } -void InputMethodFuchsia::DispatchEvent(ui::Event* event) { - DCHECK(event->IsKeyEvent()); - DispatchKeyEvent(event->AsKeyEvent()); -} - ui::EventDispatchDetails InputMethodFuchsia::DispatchKeyEvent( ui::KeyEvent* event) { DCHECK(event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED); @@ -67,53 +57,4 @@ return false; } -void InputMethodFuchsia::OnFocus() { - DCHECK(!ime_); - - // TODO(crbug.com/876934): Instantiate the IME with details about the text - // being edited. - fuchsia::ui::input::TextInputState state = {}; - state.text = ""; - ime_service_->GetInputMethodEditor( - fuchsia::ui::input::KeyboardType::TEXT, - fuchsia::ui::input::InputMethodAction::UNSPECIFIED, std::move(state), - ime_client_binding_.NewBinding(), ime_.NewRequest()); -} - -void InputMethodFuchsia::OnBlur() { - virtual_keyboard_controller_.DismissVirtualKeyboard(); - ime_client_binding_.Unbind(); - ime_.Unbind(); -} - -void InputMethodFuchsia::DidUpdateState( - fuchsia::ui::input::TextInputState state, - std::unique_ptr<fuchsia::ui::input::InputEvent> input_event) { - // The FIDL protocol for DidUpdateState allows it to be null, and so we may - // receive state updates that have no associated key. Since we're only - // interested in extracting out input events from this stream for now, we can - // just ignore state updates with no input event. - if (!input_event) - return; - - if (input_event->is_keyboard()) - event_converter_.ProcessEvent(*input_event); - else - NOTIMPLEMENTED(); -} - -void InputMethodFuchsia::OnAction( - fuchsia::ui::input::InputMethodAction action) { - if (action != fuchsia::ui::input::InputMethodAction::UNSPECIFIED) { - NOTIMPLEMENTED(); - return; - } - - // Synthesize an ENTER keypress and send it to the Window. - KeyEvent key_event(ET_KEY_PRESSED, KeyboardCode::VKEY_RETURN, - ui::DomCode::ENTER, ui::EF_NONE, ui::DomKey::ENTER, - ui::EventTimeForNow()); - DispatchKeyEvent(&key_event); -} - } // namespace ui
diff --git a/ui/base/ime/fuchsia/input_method_fuchsia.h b/ui/base/ime/fuchsia/input_method_fuchsia.h index d8ae85d..511f2c9 100644 --- a/ui/base/ime/fuchsia/input_method_fuchsia.h +++ b/ui/base/ime/fuchsia/input_method_fuchsia.h
@@ -23,54 +23,24 @@ // Handles input from physical keyboards and the IME service. class COMPONENT_EXPORT(UI_BASE_IME_FUCHSIA) InputMethodFuchsia - : public InputMethodBase, - public InputEventSink, - public fuchsia::ui::input::InputMethodEditorClient { + : public InputMethodBase { public: InputMethodFuchsia(internal::InputMethodDelegate* delegate, fuchsia::ui::views::ViewRef view_ref); ~InputMethodFuchsia() override; - fuchsia::ui::input::ImeService* ime_service() const { - return ime_service_.get(); - } + InputMethodFuchsia(InputMethodFuchsia&) = delete; + InputMethodFuchsia operator=(InputMethodFuchsia&) = delete; // InputMethodBase interface implementation. - VirtualKeyboardController* GetVirtualKeyboardController() override; - ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; - void OnCaretBoundsChanged(const TextInputClient* client) override; - void CancelComposition(const TextInputClient* client) override; - bool IsCandidatePopupOpen() const override; - void OnFocus() override; - void OnBlur() override; + VirtualKeyboardController* GetVirtualKeyboardController() final; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) final; + void OnCaretBoundsChanged(const TextInputClient* client) final; + void CancelComposition(const TextInputClient* client) final; + bool IsCandidatePopupOpen() const final; private: - // Establishes a connection to the input service and starts receiving input - // events from hard and soft keyboards. - void ConnectInputService(); - - // Terminates the connection to the input services, which stops receiving - // input events. - void DisconnectInputService(); - - // InputEventSink interface implementation. - void DispatchEvent(ui::Event* event) override; - - // InputMethodEditorClient interface implementation. - void DidUpdateState( - fuchsia::ui::input::TextInputState state, - std::unique_ptr<fuchsia::ui::input::InputEvent> input_event) override; - void OnAction(fuchsia::ui::input::InputMethodAction action) override; - - InputEventDispatcher event_converter_; - fidl::Binding<fuchsia::ui::input::InputMethodEditorClient> - ime_client_binding_; - fuchsia::ui::input::ImeServicePtr ime_service_; - fuchsia::ui::input::InputMethodEditorPtr ime_; - fuchsia::ui::input::ImeVisibilityServicePtr ime_visibility_; VirtualKeyboardControllerFuchsia virtual_keyboard_controller_; - - DISALLOW_COPY_AND_ASSIGN(InputMethodFuchsia); }; } // namespace ui
diff --git a/ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.cc b/ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.cc index f5d11304..7003199 100644 --- a/ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.cc +++ b/ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.cc
@@ -4,57 +4,104 @@ #include "ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.h" +#include <lib/fit/function.h> #include <lib/sys/cpp/component_context.h> #include <utility> #include "base/check.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/process_context.h" -#include "base/notreached.h" namespace ui { +namespace { + +// Returns the FIDL enum representation of the current InputMode. +fuchsia::input::virtualkeyboard::TextType ConvertTextInputMode( + ui::TextInputMode mode) { + switch (mode) { + case TEXT_INPUT_MODE_NUMERIC: + case TEXT_INPUT_MODE_DECIMAL: + return fuchsia::input::virtualkeyboard::TextType::NUMERIC; + + case TEXT_INPUT_MODE_TEL: + return fuchsia::input::virtualkeyboard::TextType::PHONE; + + case TEXT_INPUT_MODE_DEFAULT: + case TEXT_INPUT_MODE_NONE: + case TEXT_INPUT_MODE_TEXT: + case TEXT_INPUT_MODE_URL: + case TEXT_INPUT_MODE_EMAIL: + case TEXT_INPUT_MODE_SEARCH: + return fuchsia::input::virtualkeyboard::TextType::ALPHANUMERIC; + } +} + +} // namespace VirtualKeyboardControllerFuchsia::VirtualKeyboardControllerFuchsia( - fuchsia::ui::input::ImeService* ime_service) - : ime_service_(ime_service), - ime_visibility_( - base::ComponentContextForProcess() - ->svc() - ->Connect<fuchsia::ui::input::ImeVisibilityService>()) { - DCHECK(ime_service_); + fuchsia::ui::views::ViewRef view_ref, + ui::InputMethodBase* input_method) + : input_method_(input_method) { + DCHECK(input_method_); - ime_visibility_.set_error_handler([](zx_status_t status) { - ZX_LOG(FATAL, status) << " ImeVisibilityService lost."; + base::ComponentContextForProcess() + ->svc() + ->Connect<fuchsia::input::virtualkeyboard::ControllerCreator>() + ->Create(std::move(view_ref), + ConvertTextInputMode(input_method_->GetTextInputMode()), + controller_service_.NewRequest()); + + controller_service_.set_error_handler([this](zx_status_t status) { + ZX_LOG(ERROR, status) << "virtualkeyboard::Controller disconnected"; + keyboard_visible_ = false; }); - ime_visibility_.events().OnKeyboardVisibilityChanged = [this](bool visible) { - keyboard_visible_ = visible; - }; + WatchVisibility(); } VirtualKeyboardControllerFuchsia::~VirtualKeyboardControllerFuchsia() = default; bool VirtualKeyboardControllerFuchsia::DisplayVirtualKeyboard() { - ime_service_->ShowKeyboard(); + if (!controller_service_) + return false; + + controller_service_->SetTextType( + ConvertTextInputMode(input_method_->GetTextInputMode())); + + if (!keyboard_visible_) + controller_service_->RequestShow(); + return true; } void VirtualKeyboardControllerFuchsia::DismissVirtualKeyboard() { - ime_service_->HideKeyboard(); + if (!controller_service_) + return; + + controller_service_->RequestHide(); } void VirtualKeyboardControllerFuchsia::AddObserver( - VirtualKeyboardControllerObserver* observer) { - NOTIMPLEMENTED(); -} + VirtualKeyboardControllerObserver* observer) {} void VirtualKeyboardControllerFuchsia::RemoveObserver( - VirtualKeyboardControllerObserver* observer) { - NOTIMPLEMENTED(); -} + VirtualKeyboardControllerObserver* observer) {} bool VirtualKeyboardControllerFuchsia::IsKeyboardVisible() { return keyboard_visible_; } +void VirtualKeyboardControllerFuchsia::WatchVisibility() { + if (!controller_service_) + return; + + controller_service_->WatchVisibility(fit::bind_member( + this, &VirtualKeyboardControllerFuchsia::OnVisibilityChange)); +} + +void VirtualKeyboardControllerFuchsia::OnVisibilityChange(bool is_visible) { + keyboard_visible_ = is_visible; + WatchVisibility(); +} + } // namespace ui
diff --git a/ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.h b/ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.h index f4118cd1..1adc5692 100644 --- a/ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.h +++ b/ui/base/ime/fuchsia/virtual_keyboard_controller_fuchsia.h
@@ -5,10 +5,13 @@ #ifndef UI_BASE_IME_FUCHSIA_VIRTUAL_KEYBOARD_CONTROLLER_FUCHSIA_H_ #define UI_BASE_IME_FUCHSIA_VIRTUAL_KEYBOARD_CONTROLLER_FUCHSIA_H_ +#include <fuchsia/input/virtualkeyboard/cpp/fidl.h> #include <fuchsia/ui/input/cpp/fidl.h> +#include <lib/ui/scenic/cpp/view_ref_pair.h> #include "base/component_export.h" #include "base/macros.h" +#include "ui/base/ime/input_method_base.h" #include "ui/base/ime/virtual_keyboard_controller.h" namespace ui { @@ -17,12 +20,15 @@ class COMPONENT_EXPORT(UI_BASE_IME) VirtualKeyboardControllerFuchsia : public VirtualKeyboardController { public: - // |ime_service| must outlive |this|. - explicit VirtualKeyboardControllerFuchsia( - fuchsia::ui::input::ImeService* ime_service); - + // |input_method| must outlive |this|. + VirtualKeyboardControllerFuchsia(fuchsia::ui::views::ViewRef view_ref, + ui::InputMethodBase* input_method); ~VirtualKeyboardControllerFuchsia() override; + VirtualKeyboardControllerFuchsia(VirtualKeyboardControllerFuchsia&) = delete; + VirtualKeyboardControllerFuchsia operator=( + VirtualKeyboardControllerFuchsia&) = delete; + // VirtualKeyboardController implementation. bool DisplayVirtualKeyboard() override; void DismissVirtualKeyboard() override; @@ -31,11 +37,15 @@ bool IsKeyboardVisible() override; private: - fuchsia::ui::input::ImeService* const ime_service_; - fuchsia::ui::input::ImeVisibilityServicePtr ime_visibility_; - bool keyboard_visible_ = false; + // Initiates a "hanging get" request for virtual keyboard visibility. + void WatchVisibility(); - DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardControllerFuchsia); + // Handles the visibility change response from the service. + void OnVisibilityChange(bool is_visible); + + ui::InputMethodBase* const input_method_; + fuchsia::input::virtualkeyboard::ControllerPtr controller_service_; + bool keyboard_visible_ = false; }; } // namespace ui
diff --git a/ui/chromeos/events/event_rewriter_chromeos.cc b/ui/chromeos/events/event_rewriter_chromeos.cc index dd51892e..26531c7 100644 --- a/ui/chromeos/events/event_rewriter_chromeos.cc +++ b/ui/chromeos/events/event_rewriter_chromeos.cc
@@ -1640,7 +1640,7 @@ return; } } - } else if (!::features::IsImprovedKeyboardShortcutsEnabled()) { + } else { // Remap Search + digit row to F1~F12. static const SearchToFunctionMap kNumberKeysToFkeys[] = { {DomCode::DIGIT1, {EF_NONE, DomCode::F1, DomKey::F1, VKEY_F1}}, @@ -1657,9 +1657,24 @@ {DomCode::EQUAL, {EF_NONE, DomCode::F12, DomKey::F12, VKEY_F12}}}; for (const auto& map : kNumberKeysToFkeys) { if (state->code == map.input_dom_code) { - state->flags &= ~EF_COMMAND_DOWN; - ApplyRemapping(map.result, state); - RecordSearchPlusDigitFKeyRewrite(key_event.type(), state->key_code); + if (!::features::IsImprovedKeyboardShortcutsEnabled()) { + state->flags &= ~EF_COMMAND_DOWN; + ApplyRemapping(map.result, state); + RecordSearchPlusDigitFKeyRewrite(key_event.type(), state->key_code); + } else { + // Only trigger the notification for F1-F10. + // + // Because of this legacy remapping 2 virtual desk shortcuts + // implicitly used F11 and F12 because the shortcut included + // Search and either minus or equal. Do not trigger a + // notification for this case because it wasn't the users intent. + if (static_cast<int>(map.result.code) <= + static_cast<int>(DomCode::F10)) { + DCHECK_GE(static_cast<int>(map.result.code), + static_cast<int>(DomCode::F1)); + delegate_->NotifyDeprecatedFKeyRewrite(); + } + } return; } }
diff --git a/ui/chromeos/events/event_rewriter_chromeos.h b/ui/chromeos/events/event_rewriter_chromeos.h index d92d6731..9e7acb0 100644 --- a/ui/chromeos/events/event_rewriter_chromeos.h +++ b/ui/chromeos/events/event_rewriter_chromeos.h
@@ -120,6 +120,11 @@ // returns true if the notification was shown. virtual bool NotifyDeprecatedRightClickRewrite() = 0; + // Used to send a notification about Search+Digit Fkey rewrites being + // deprecated. The notification is only sent once per user session, + // and this function returns true if the notification was shown. + virtual bool NotifyDeprecatedFKeyRewrite() = 0; + // Used to send a notification about Alt based key rewrite being deprecated. // The notification is only sent once per user session, and this function // returns true if the notification was shown.
diff --git a/ui/events/devices/device_data_manager.cc b/ui/events/devices/device_data_manager.cc index cf43bed..f2b02e8a 100644 --- a/ui/events/devices/device_data_manager.cc +++ b/ui/events/devices/device_data_manager.cc
@@ -288,6 +288,15 @@ observers_.RemoveObserver(observer); } +void DeviceDataManager::ResetDeviceListsForTest() { + touchscreen_devices_.clear(); + keyboard_devices_.clear(); + mouse_devices_.clear(); + touchpad_devices_.clear(); + uncategorized_devices_.clear(); + device_lists_complete_ = false; +} + void DeviceDataManager::SetTouchscreensEnabled(bool enabled) { touch_screens_enabled_ = enabled; }
diff --git a/ui/events/devices/device_data_manager.h b/ui/events/devices/device_data_manager.h index 08fb678e..b15a3c4 100644 --- a/ui/events/devices/device_data_manager.h +++ b/ui/events/devices/device_data_manager.h
@@ -68,6 +68,11 @@ void AddObserver(InputDeviceEventObserver* observer); void RemoveObserver(InputDeviceEventObserver* observer); + // Resets all device lists and |device_lists_complete_|. This method exists + // because the DeviceDataManager instance is created early in test suite setup + // and is hard to replace for tests that require a fresh one. + void ResetDeviceListsForTest(); + protected: DeviceDataManager();
diff --git a/ui/gfx/linux/client_native_pixmap_dmabuf.cc b/ui/gfx/linux/client_native_pixmap_dmabuf.cc index 86c3dce..2ee8d16b 100644 --- a/ui/gfx/linux/client_native_pixmap_dmabuf.cc +++ b/ui/gfx/linux/client_native_pixmap_dmabuf.cc
@@ -94,20 +94,6 @@ bool ClientNativePixmapDmaBuf::IsConfigurationSupported( gfx::BufferFormat format, gfx::BufferUsage usage) { - bool disable_yuv_biplanar = true; -#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMECAST) - // IsConfigurationSupported(SCANOUT_CPU_READ_WRITE) is used by the renderer - // to tell whether the platform supports sampling a given format. Zero-copy - // video capture and encoding requires gfx::BufferFormat::YUV_420_BIPLANAR to - // be supported by the renderer. Most of Chrome OS platforms support it, so - // enable it by default, with a switch that allows an explicit disable on - // platforms known to have problems, e.g. the Tegra-based nyan." - // TODO(crbug.com/982201): move gfx::BufferFormat::YUV_420_BIPLANAR out - // of if defined(ARCH_CPU_X86_FAMLIY) when Tegra is no longer supported. - disable_yuv_biplanar = base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableYuv420Biplanar); -#endif - switch (usage) { case gfx::BufferUsage::GPU_READ: return format == gfx::BufferFormat::BGR_565 || @@ -130,10 +116,8 @@ if (format == gfx::BufferFormat::RG_88 && !AllowCpuMappableBuffers()) return false; - if (!disable_yuv_biplanar && - format == gfx::BufferFormat::YUV_420_BIPLANAR) { + if (format == gfx::BufferFormat::YUV_420_BIPLANAR) return true; - } return #if defined(ARCH_CPU_X86_FAMILY) @@ -158,10 +142,8 @@ if (!AllowCpuMappableBuffers()) return false; - if (!disable_yuv_biplanar && - format == gfx::BufferFormat::YUV_420_BIPLANAR) { + if (format == gfx::BufferFormat::YUV_420_BIPLANAR) return true; - } return #if defined(ARCH_CPU_X86_FAMILY)
diff --git a/ui/gfx/switches.cc b/ui/gfx/switches.cc index 16eeda0d..0f746ea 100644 --- a/ui/gfx/switches.cc +++ b/ui/gfx/switches.cc
@@ -16,10 +16,6 @@ const char kDisableFontSubpixelPositioning[] = "disable-font-subpixel-positioning"; -// Disable a NV12 format buffer allocation with -// gfx::BufferUsage::SCANOUT_CPU_READ_WRITE usage. -const char kDisableYuv420Biplanar[] = "disable-yuv420-biplanar"; - // Enable native CPU-mappable GPU memory buffer support on Linux. const char kEnableNativeGpuMemoryBuffers[] = "enable-native-gpu-memory-buffers";
diff --git a/ui/gfx/switches.h b/ui/gfx/switches.h index fa86fc52..f8fc7fe 100644 --- a/ui/gfx/switches.h +++ b/ui/gfx/switches.h
@@ -12,7 +12,6 @@ GFX_SWITCHES_EXPORT extern const char kAnimationDurationScale[]; GFX_SWITCHES_EXPORT extern const char kDisableFontSubpixelPositioning[]; -GFX_SWITCHES_EXPORT extern const char kDisableYuv420Biplanar[]; GFX_SWITCHES_EXPORT extern const char kEnableNativeGpuMemoryBuffers[]; GFX_SWITCHES_EXPORT extern const char kForcePrefersReducedMotion[]; GFX_SWITCHES_EXPORT extern const char kHeadless[];
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm index eecf660..2e93f10 100644 --- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm +++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
@@ -801,7 +801,12 @@ void NativeWidgetMacNSWindowHost::OnMouseEvent( std::unique_ptr<ui::Event> event) { - root_view_->GetWidget()->OnMouseEvent(event->AsMouseEvent()); + ui::MouseEvent* mouse_event = event->AsMouseEvent(); + root_view_->GetWidget()->OnMouseEvent(mouse_event); + if (scoped_cg_window_id_) { + scoped_cg_window_id_->OnMouseMoved(mouse_event->location_f(), + window_bounds_in_screen_.size()); + } } void NativeWidgetMacNSWindowHost::OnGestureEvent(
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc index 2315e34..9b312a06 100644 --- a/ui/views/controls/webview/web_dialog_view.cc +++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -96,6 +96,8 @@ if (delegate_) { for (const auto& accelerator : delegate_->GetAccelerators()) AddAccelerator(accelerator); + RegisterWindowWillCloseCallback(base::BindOnce( + &WebDialogView::NotifyDialogWillClose, base::Unretained(this))); } } @@ -179,10 +181,6 @@ //////////////////////////////////////////////////////////////////////////////// // WebDialogView, views::WidgetDelegate implementation: -bool WebDialogView::OnCloseRequested(Widget::ClosedReason close_reason) { - return !delegate_ || delegate_->DeprecatedOnDialogCloseRequested(); -} - bool WebDialogView::CanMaximize() const { if (delegate_) return delegate_->CanMaximizeDialog(); @@ -477,6 +475,11 @@ web_view_->LoadInitialURL(GetDialogContentURL()); } +void WebDialogView::NotifyDialogWillClose() { + if (delegate_) + delegate_->OnDialogWillClose(); +} + BEGIN_METADATA(WebDialogView, ClientView) ADD_READONLY_PROPERTY_METADATA(ObservableWebView*, WebView); END_METADATA
diff --git a/ui/views/controls/webview/web_dialog_view.h b/ui/views/controls/webview/web_dialog_view.h index dadead33..8c5edd6 100644 --- a/ui/views/controls/webview/web_dialog_view.h +++ b/ui/views/controls/webview/web_dialog_view.h
@@ -99,7 +99,6 @@ views::CloseRequestResult OnWindowCloseRequested() override; // WidgetDelegate: - bool OnCloseRequested(Widget::ClosedReason close_reason) override; bool CanMaximize() const override; std::u16string GetWindowTitle() const override; std::u16string GetAccessibleWindowTitle() const override; @@ -180,6 +179,8 @@ // Accessor used by metadata only. ObservableWebView* GetWebView() const { return web_view_; } + void NotifyDialogWillClose(); + // This view is a delegate to the HTML content since it needs to get notified // about when the dialog is closing. For all other actions (besides dialog // closing) we delegate to the creator of this view, which we keep track of
diff --git a/ui/web_dialogs/web_dialog_delegate.cc b/ui/web_dialogs/web_dialog_delegate.cc index 3dfa89c..189c58cc 100644 --- a/ui/web_dialogs/web_dialog_delegate.cc +++ b/ui/web_dialogs/web_dialog_delegate.cc
@@ -28,10 +28,6 @@ return true; } -bool WebDialogDelegate::DeprecatedOnDialogCloseRequested() { - return true; -} - bool WebDialogDelegate::ShouldCenterDialogTitleText() const { return false; }
diff --git a/ui/web_dialogs/web_dialog_delegate.h b/ui/web_dialogs/web_dialog_delegate.h index ac56b2f4..dc7fe5f 100644 --- a/ui/web_dialogs/web_dialog_delegate.h +++ b/ui/web_dialogs/web_dialog_delegate.h
@@ -102,13 +102,13 @@ // closed. If this returns true, the dialog is closed, otherwise the // dialog remains open. Default implementation returns true. virtual bool OnDialogCloseRequested(); - // Use `OnDialogCloseRequested()` instead. This one is called too late in the - // closing process, so returning false here will leave you a half-broken - // dialog. Currently, `AddSupervisionDialog` relies on this to record - // histogram correctly. - // - // TODO(crbug.com/1110759): remove this function. - virtual bool DeprecatedOnDialogCloseRequested(); + + // Called when the dialog's window is certainly about to close, but teardown + // has not started yet. This differs from OnDialogCloseRequested in that + // OnDialogCloseRequested is part of the process of deciding whether to close + // a window, while OnDialogWillClose is called as soon as it is known for + // certain that the window is about to be closed. + virtual void OnDialogWillClose() {} // A callback to notify the delegate that the dialog is about to close due to // the user pressing the ESC key.
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_list_item.html b/ui/webui/resources/cr_components/chromeos/network/network_list_item.html index 8b02fc5..ce15407 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_list_item.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_list_item.html
@@ -184,7 +184,7 @@ </template> <template is="dom-if" if="[[isESimPendingProfile_]]" restamp> <cr-button id="installButton" - aria-label$="[[getItemName_(item)]], [[i18n('networkListItemDownload')]]" + aria-label$="[[getInstallBtnA11yLabel_(item)]]" on-click="onInstallButtonClick_" disabled="[[disabled_]]"> <iron-icon icon="network:download"></iron-icon>
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_list_item.js b/ui/webui/resources/cr_components/chromeos/network/network_list_item.js index fbf83c11..1572515 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_list_item.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_list_item.js
@@ -710,6 +710,14 @@ }, /** + * @return {string} + * @private + */ + getInstallBtnA11yLabel_() { + return this.i18n('networkListItemDownloadA11yLabel', this.getItemName_()); + }, + + /** * @param {boolean} newValue * @param {boolean|undefined} oldValue * @private
diff --git a/ui/webui/resources/cr_components/customize_themes/BUILD.gn b/ui/webui/resources/cr_components/customize_themes/BUILD.gn index 526e533..72c74036 100644 --- a/ui/webui/resources/cr_components/customize_themes/BUILD.gn +++ b/ui/webui/resources/cr_components/customize_themes/BUILD.gn
@@ -49,6 +49,7 @@ "//skia/public/mojom:mojom_webui_js", "//third_party/polymer/v3_0/components-chromium/paper-tooltip:paper-tooltip", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/managed_dialog", "//ui/webui/resources/cr_elements/cr_grid", "//ui/webui/resources/js:i18n_behavior.m", ]
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.html b/ui/webui/resources/cr_components/customize_themes/customize_themes.html index e4a252f..e5c0dc1 100644 --- a/ui/webui/resources/cr_components/customize_themes/customize_themes.html +++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.html
@@ -155,7 +155,7 @@ <cr-theme-icon id="autogeneratedTheme" selected$="[[isThemeIconSelected_('autogenerated', selectedTheme)]]"> </cr-theme-icon> - <div id="colorPickerIcon"></div> + <div id="colorPickerIcon" hidden="[[isForcedTheme_(selectedTheme)]]"></div> <input id="colorPicker" type="color" on-change="onCustomFrameColorChange_"> </div> @@ -192,3 +192,9 @@ </div> </template> </cr-grid> +<template is="dom-if" if="[[showManagedThemeDialog_]]" restamp> + <managed-dialog on-close="onManagedDialogClosed_" + title="[[i18n('themeManagedDialogTitle')]]" + body="[[i18n('themeManagedDialogBody')]]"> + </managed-dialog> +</template>
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.js b/ui/webui/resources/cr_components/customize_themes/customize_themes.js index f1260fcf..7a4bd3d 100644 --- a/ui/webui/resources/cr_components/customize_themes/customize_themes.js +++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.js
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '../managed_dialog/managed_dialog.js'; import '../../cr_elements/cr_button/cr_button.m.js'; import '../../cr_elements/cr_icon_button/cr_icon_button.m.js'; import '../../cr_elements/cr_icons_css.m.js'; @@ -62,6 +63,12 @@ /** @private {!Array<!ChromeTheme>} */ chromeThemes_: Array, + + /** @private */ + showManagedThemeDialog_: { + type: Boolean, + value: false, + } }; } @@ -120,11 +127,21 @@ /** @private */ onAutogeneratedThemeClick_() { + if (this.isForcedTheme_()) { + // If the applied theme is managed, show a dialog to inform the user. + this.showManagedThemeDialog_ = true; + return; + } this.$.colorPicker.click(); } /** @private */ onDefaultThemeClick_() { + if (this.isForcedTheme_()) { + // If the applied theme is managed, show a dialog to inform the user. + this.showManagedThemeDialog_ = true; + return; + } this.handler_.applyDefaultTheme(); if (this.autoConfirmThemeChanges) { this.handler_.confirmThemeChanges(); @@ -136,6 +153,11 @@ * @private */ onChromeThemeClick_(e) { + if (this.isForcedTheme_()) { + // If the applied theme is managed, show a dialog to inform the user. + this.showManagedThemeDialog_ = true; + return; + } this.handler_.applyChromeTheme(this.$.themes.itemForElement(e.target).id); if (this.autoConfirmThemeChanges) { this.handler_.confirmThemeChanges(); @@ -230,6 +252,14 @@ } /** + * @return {boolean} + * @private + */ + isForcedTheme_() { + return !!this.selectedTheme && this.selectedTheme.isForced; + } + + /** * @param {SkColor} skColor * @return {string} * @private @@ -237,6 +267,11 @@ skColorToRgba_(skColor) { return skColorToRgba(skColor); } + + /** @private */ + onManagedDialogClosed_() { + this.showManagedThemeDialog_ = false; + } } customElements.define(CustomizeThemesElement.is, CustomizeThemesElement);
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.mojom b/ui/webui/resources/cr_components/customize_themes/customize_themes.mojom index 0e1be49..2472c60 100644 --- a/ui/webui/resources/cr_components/customize_themes/customize_themes.mojom +++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.mojom
@@ -52,6 +52,8 @@ ThemeType type; // Additional info about the theme depending on the type. ThemeInfo info; + // Whether theme is forced through a policy. + bool is_forced; }; // Used by the component to bootstrap bidirectional communication.
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn index 4365bc8d..ffc2b38 100644 --- a/ui/webui/resources/cr_elements/BUILD.gn +++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -42,6 +42,7 @@ in_files = [ "cr_search_field/cr_search_field_behavior.js", "cr_splitter/cr_splitter.js", + "find_shortcut_behavior.js", ] } @@ -103,8 +104,6 @@ "cr_toggle/cr_toggle.js", "cr_view_manager/cr_view_manager.html", "cr_view_manager/cr_view_manager.js", - "find_shortcut_behavior.html", - "find_shortcut_behavior.js", "hidden_style_css.html", "icons.html", "md_select_css.html", @@ -188,7 +187,6 @@ "cr_toolbar/cr_toolbar_search_field.js", "cr_toolbar/cr_toolbar_selection_overlay.js", "cr_view_manager/cr_view_manager.m.js", - "find_shortcut_behavior.m.js", "hidden_style_css.m.js", "icons.m.js", "md_select_css.m.js", @@ -287,7 +285,6 @@ deps = [ ":cr_container_shadow_behavior", ":cr_scrollable_behavior", - ":find_shortcut_behavior", ] } @@ -299,15 +296,6 @@ deps = [ "//ui/webui/resources/js:assert" ] } -js_library("find_shortcut_behavior") { - deps = [ - "//ui/webui/resources/js:assert", - "//ui/webui/resources/js:cr", - "//ui/webui/resources/js:util", - "//ui/webui/resources/js/cr/ui:keyboard_shortcut_list", - ] -} - # Targets for auto-generating Polymer 3 JS Modules. polymer_modulizer("action_link_css") { @@ -374,7 +362,6 @@ input_files = [ "cr_container_shadow_behavior.js", "cr_scrollable_behavior.js", - "find_shortcut_behavior.js", ] } @@ -435,7 +422,7 @@ deps = [ ":cr_container_shadow_behavior.m", ":cr_scrollable_behavior.m", - ":find_shortcut_behavior.m", + ":find_shortcut_behavior", ] } @@ -456,17 +443,13 @@ extra_deps = [ ":modulize" ] } -js_library("find_shortcut_behavior.m") { - sources = [ - "$root_gen_dir/ui/webui/resources/cr_elements/find_shortcut_behavior.m.js", - ] +js_library("find_shortcut_behavior") { deps = [ "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:util.m", "//ui/webui/resources/js/cr/ui:keyboard_shortcut_list.m", ] - extra_deps = [ ":modulize" ] } html_to_js("web_components") {
diff --git a/ui/webui/resources/cr_elements/find_shortcut_behavior.js b/ui/webui/resources/cr_elements/find_shortcut_behavior.js index cee42c6..c39e606 100644 --- a/ui/webui/resources/cr_elements/find_shortcut_behavior.js +++ b/ui/webui/resources/cr_elements/find_shortcut_behavior.js
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// #import {assert, assertNotReached} from '../js/assert.m.js'; -// #import {isMac} from '../js/cr.m.js'; -// #import {isTextInputElement} from '../js/util.m.js'; -// #import {KeyboardShortcutList} from '../js/cr/ui/keyboard_shortcut_list.m.js'; +import {assert, assertNotReached} from '../js/assert.m.js'; +import {isMac} from '../js/cr.m.js'; +import {KeyboardShortcutList} from '../js/cr/ui/keyboard_shortcut_list.m.js'; +import {isTextInputElement} from '../js/util.m.js'; /** * @fileoverview Listens for a find keyboard shortcut (i.e. Ctrl/Cmd+f or /) @@ -13,7 +13,7 @@ * top of the stack will be notified that a find shortcut has been invoked. */ -/* #export */ const FindShortcutManager = (() => { +export const FindShortcutManager = (() => { /** * Stack of listeners. Only the top listener will handle the shortcut. * @type {!Array} @@ -28,9 +28,8 @@ */ let modalContextOpen = false; - const shortcutCtrlF = - new cr.ui.KeyboardShortcutList(cr.isMac ? 'meta|f' : 'ctrl|f'); - const shortcutSlash = new cr.ui.KeyboardShortcutList('/'); + const shortcutCtrlF = new KeyboardShortcutList(isMac ? 'meta|f' : 'ctrl|f'); + const shortcutSlash = new KeyboardShortcutList('/'); window.addEventListener('keydown', e => { if (e.defaultPrevented || listeners.length === 0) { @@ -76,7 +75,7 @@ * Used to determine how to handle find shortcut invocations. * @polymerBehavior */ -/* #export */ const FindShortcutBehavior = { +export const FindShortcutBehavior = { /** * @type {boolean} * @protected
diff --git a/url/gurl.cc b/url/gurl.cc index c656255..2107c30b 100644 --- a/url/gurl.cc +++ b/url/gurl.cc
@@ -68,8 +68,8 @@ InitializeFromCanonicalSpec(); } -template<typename STR> -void GURL::InitCanonical(base::BasicStringPiece<STR> input_spec, +template <typename CharT> +void GURL::InitCanonical(base::BasicStringPiece<CharT> input_spec, bool trim_path_end) { url::StdStringCanonOutput output(&spec_); is_valid_ = url::Canonicalize(
diff --git a/url/gurl.h b/url/gurl.h index f8ee81e..7dcf1d55 100644 --- a/url/gurl.h +++ b/url/gurl.h
@@ -45,8 +45,8 @@ // will know to escape this and produce the desired result. class COMPONENT_EXPORT(URL) GURL { public: - typedef url::StringPieceReplacements<std::string> Replacements; - typedef url::StringPieceReplacements<std::u16string> ReplacementsW; + typedef url::StringPieceReplacements<char> Replacements; + typedef url::StringPieceReplacements<char16_t> ReplacementsW; // Creates an empty, invalid URL. GURL(); @@ -448,8 +448,8 @@ enum RetainWhiteSpaceSelector { RETAIN_TRAILING_PATH_WHITEPACE }; GURL(const std::string& url_string, RetainWhiteSpaceSelector); - template<typename STR> - void InitCanonical(base::BasicStringPiece<STR> input_spec, + template <typename CharT> + void InitCanonical(base::BasicStringPiece<CharT> input_spec, bool trim_path_end); void InitializeFromCanonicalSpec();
diff --git a/url/url_canon_stdstring.h b/url/url_canon_stdstring.h index c9a3fee..44edab7f 100644 --- a/url/url_canon_stdstring.h +++ b/url/url_canon_stdstring.h
@@ -59,11 +59,11 @@ // references to std::strings. // Note: Extra const char* overloads are necessary to break ambiguities that // would otherwise exist for char literals. -template <typename STR> -class StringPieceReplacements : public Replacements<typename STR::value_type> { +template <typename CharT> +class StringPieceReplacements : public Replacements<CharT> { private: - using CharT = typename STR::value_type; - using StringPieceT = base::BasicStringPiece<STR>; + using StringT = std::basic_string<CharT>; + using StringPieceT = base::BasicStringPiece<CharT>; using ParentT = Replacements<CharT>; using SetterFun = void (ParentT::*)(const CharT*, const Component&); @@ -74,35 +74,35 @@ public: void SetSchemeStr(const CharT* str) { SetImpl(&ParentT::SetScheme, str); } void SetSchemeStr(StringPieceT str) { SetImpl(&ParentT::SetScheme, str); } - void SetSchemeStr(const STR&&) = delete; + void SetSchemeStr(const StringT&&) = delete; void SetUsernameStr(const CharT* str) { SetImpl(&ParentT::SetUsername, str); } void SetUsernameStr(StringPieceT str) { SetImpl(&ParentT::SetUsername, str); } - void SetUsernameStr(const STR&&) = delete; + void SetUsernameStr(const StringT&&) = delete; void SetPasswordStr(const CharT* str) { SetImpl(&ParentT::SetPassword, str); } void SetPasswordStr(StringPieceT str) { SetImpl(&ParentT::SetPassword, str); } - void SetPasswordStr(const STR&&) = delete; + void SetPasswordStr(const StringT&&) = delete; void SetHostStr(const CharT* str) { SetImpl(&ParentT::SetHost, str); } void SetHostStr(StringPieceT str) { SetImpl(&ParentT::SetHost, str); } - void SetHostStr(const STR&&) = delete; + void SetHostStr(const StringT&&) = delete; void SetPortStr(const CharT* str) { SetImpl(&ParentT::SetPort, str); } void SetPortStr(StringPieceT str) { SetImpl(&ParentT::SetPort, str); } - void SetPortStr(const STR&&) = delete; + void SetPortStr(const StringT&&) = delete; void SetPathStr(const CharT* str) { SetImpl(&ParentT::SetPath, str); } void SetPathStr(StringPieceT str) { SetImpl(&ParentT::SetPath, str); } - void SetPathStr(const STR&&) = delete; + void SetPathStr(const StringT&&) = delete; void SetQueryStr(const CharT* str) { SetImpl(&ParentT::SetQuery, str); } void SetQueryStr(StringPieceT str) { SetImpl(&ParentT::SetQuery, str); } - void SetQueryStr(const STR&&) = delete; + void SetQueryStr(const StringT&&) = delete; void SetRefStr(const CharT* str) { SetImpl(&ParentT::SetRef, str); } void SetRefStr(StringPieceT str) { SetImpl(&ParentT::SetRef, str); } - void SetRefStr(const STR&&) = delete; + void SetRefStr(const StringT&&) = delete; }; } // namespace url
diff --git a/weblayer/browser/signin_url_loader_throttle.cc b/weblayer/browser/signin_url_loader_throttle.cc index e5660f5..f07f1754 100644 --- a/weblayer/browser/signin_url_loader_throttle.cc +++ b/weblayer/browser/signin_url_loader_throttle.cc
@@ -4,12 +4,12 @@ #include "weblayer/browser/signin_url_loader_throttle.h" -#include "base/task/post_task.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/signin/core/browser/signin_header_helper.h" #include "components/signin/public/base/account_consistency_method.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "google_apis/gaia/gaia_auth_util.h" #include "net/base/url_util.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" @@ -188,8 +188,8 @@ // Post a task even if we are already on the UI thread to avoid making any // requests while processing a throttle event. - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&ProcessMirrorHeader, web_contents_getter_, params)); }
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc index c6d4ee2..2640654 100644 --- a/weblayer/browser/tab_impl.cc +++ b/weblayer/browser/tab_impl.cc
@@ -838,7 +838,8 @@ // Reset state that an earlier call to Navigation::SetUserAgentString() // could have modified. embedder_support::SetDesktopUserAgentOverride( - web_contents_.get(), embedder_support::GetUserAgentMetadata()); + web_contents_.get(), embedder_support::GetUserAgentMetadata(), + /* override_in_new_tabs= */ false); web_contents_->SetRendererInitiatedUserAgentOverrideOption( content::NavigationController::UA_OVERRIDE_INHERIT);