diff --git a/DEPS b/DEPS index a4bee8e..d4d1a3cd 100644 --- a/DEPS +++ b/DEPS
@@ -79,11 +79,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': '76546506d19534bf8373989bab6bca26f4f9c759', + 'skia_revision': '18c46b553a3943337403b510be0a7dd75aacf35c', # 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': 'e466ab96bed6713190136f6abdcbcb8908dc2b57', + 'v8_revision': '5dfbb74d761f1ab521314314367577909e0772f3', # 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. @@ -91,7 +91,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '0e65454df2b66c7dada831f24752c677f86e43ff', + 'angle_revision': 'da91c9a6d86c9ecd21c6ac724cf9576d7ee310d2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -103,7 +103,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'b0fb8cc23c0ae555726f873101961676f96f6f07', + 'pdfium_revision': '9f72c45cbcd159f7b811589be1e896c9781e8394', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -111,7 +111,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': '7e5dd25d47face6deb452823ae4f40c4c7ca375a', + 'boringssl_revision': '61dedd681501616de5928fe5c0eac6640d4de0c1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -135,7 +135,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'aa41a69e728232222f4c696dab70af09eb2213e0', + 'catapult_revision': 'e653c4b823f98c26bd29e4cf4e3bdacdffb4b041', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -272,7 +272,7 @@ }, 'src/third_party/android_tools': { - 'url': Var('chromium_git') + '/android_tools.git' + '@' + 'c9f9bbf0a6c862fbef6115e80e8617093cd58e6b', + 'url': Var('chromium_git') + '/android_tools.git' + '@' + '9a70d48fcdd68cd0e7e968f342bd767ee6323bd1', 'condition': 'checkout_android', }, @@ -336,7 +336,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6a60d7586a1c6f921026fba2c819467d069585e5', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '71236c3af69153e838b29699a072bc03fa33eab3', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -490,7 +490,7 @@ Var('chromium_git') + '/webm/libwebm.git' + '@' + 'b03c65468b06d097f27235d93d76bfc45f490ede', 'src/third_party/libyuv': - Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'ffec313dbe58c6b97d4943387bda618dccbe4591', # from r1694 + Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'b792e0dbc152dbeea6f4a5ba59dccd05c32eb3c2', # from r1697 'src/third_party/lighttpd': { 'url': Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'), @@ -652,7 +652,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a182a9ad3078aca566d8355eabf2d9f56f70ee82', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '6f7bc08457fd89868c3bd14335905d4b195065e7', # commit position 21742 + Var('webrtc_git') + '/src.git' + '@' + '2b67f5c65f7a331650df868148a495c921b970f8', # commit position 21742 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index e7b82ae..22961a3 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -456,6 +456,18 @@ False, (), ), + ( + 'sqlite3_initialize', + ( + 'Instead of sqlite3_initialize, depend on //sql, ', + '#include "sql/initialize.h" and use sql::EnsureSqliteInitialized().', + ), + True, + ( + r'^sql/initialization\.(cc|h)$', + r'^third_party/sqlite/.*\.(c|cc|h)$', + ), + ), ) @@ -522,8 +534,8 @@ # Bypass the AUTHORS check for these accounts. _KNOWN_ROBOTS = set( '%s-chromium-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com' % s - for s in ('angle', 'catapult', 'depot-tools', 'nacl', 'pdfium', 'skia', - 'src-internal', 'webrtc')) + for s in ('afdo', 'angle', 'catapult', 'depot-tools', 'nacl', 'pdfium', + 'skia', 'src-internal', 'webrtc')) def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 6fa7fc3..c0a4127 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -44,6 +44,7 @@ #include "components/policy/content/policy_blacklist_navigation_throttle.h" #include "components/safe_browsing/browser/browser_url_loader_throttle.h" #include "components/safe_browsing/browser/mojo_safe_browsing_impl.h" +#include "components/safe_browsing/features.h" #include "components/spellcheck/spellcheck_build_features.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/browser_thread.h" @@ -566,7 +567,8 @@ service_manager::BinderRegistry* registry, blink::AssociatedInterfaceRegistry* associated_registry, content::RenderProcessHost* render_process_host) { - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { + if (base::FeatureList::IsEnabled(network::features::kNetworkService) || + base::FeatureList::IsEnabled(safe_browsing::kCheckByURLLoaderThrottle)) { content::ResourceContext* resource_context = render_process_host->GetBrowserContext()->GetResourceContext(); registry->AddInterface( @@ -585,17 +587,25 @@ const network::ResourceRequest& request, content::ResourceContext* resource_context, const base::RepeatingCallback<content::WebContents*()>& wc_getter, - content::NavigationUIData* navigation_ui_data) { + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); std::vector<std::unique_ptr<content::URLLoaderThrottle>> result; - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - auto safe_browsing_throttle = - safe_browsing::BrowserURLLoaderThrottle::MaybeCreate( - GetSafeBrowsingUrlCheckerDelegate(), wc_getter); - if (safe_browsing_throttle) - result.push_back(std::move(safe_browsing_throttle)); + if (base::FeatureList::IsEnabled(network::features::kNetworkService) || + base::FeatureList::IsEnabled(safe_browsing::kCheckByURLLoaderThrottle)) { + auto* delegate = GetSafeBrowsingUrlCheckerDelegate(); + if (delegate && !delegate->ShouldSkipRequestCheck( + resource_context, request.url, frame_tree_node_id, + -1 /* render_process_id */, -1 /* render_frame_id */, + request.originated_from_service_worker)) { + auto safe_browsing_throttle = + safe_browsing::BrowserURLLoaderThrottle::MaybeCreate(delegate, + wc_getter); + if (safe_browsing_throttle) + result.push_back(std::move(safe_browsing_throttle)); + } } return result;
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index f1348387..e5542010 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -157,7 +157,8 @@ const network::ResourceRequest& request, content::ResourceContext* resource_context, const base::RepeatingCallback<content::WebContents*()>& wc_getter, - content::NavigationUIData* navigation_ui_data) override; + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id) override; bool ShouldOverrideUrlLoading(int frame_tree_node_id, bool browser_initiated, const GURL& gurl,
diff --git a/android_webview/browser/aw_safe_browsing_resource_throttle.cc b/android_webview/browser/aw_safe_browsing_resource_throttle.cc index 28dfc8f2..9f9b3ef 100644 --- a/android_webview/browser/aw_safe_browsing_resource_throttle.cc +++ b/android_webview/browser/aw_safe_browsing_resource_throttle.cc
@@ -6,10 +6,11 @@ #include <memory> -#include "android_webview/browser/aw_contents_client_bridge.h" #include "android_webview/browser/aw_safe_browsing_whitelist_manager.h" #include "android_webview/browser/aw_url_checker_delegate_impl.h" +#include "components/safe_browsing/common/safebrowsing_constants.h" #include "components/safe_browsing/db/v4_protocol_manager_util.h" +#include "content/public/browser/resource_request_info.h" #include "net/url_request/url_request.h" namespace android_webview { @@ -44,7 +45,17 @@ } bool IsCancelledBySafeBrowsing(const net::URLRequest* request) { - return request->GetUserData(kCancelledBySafeBrowsingUserDataKey) != nullptr; + // Check whether the request is cancelled by + // AwSafeBrowsingParallelResourceThrottle. + if (request->GetUserData(kCancelledBySafeBrowsingUserDataKey)) + return true; + + // Check whether the request is cancelled by + // safe_browsing::{Browser,Renderer}URLLoaderThrottle. + const content::ResourceRequestInfo* request_info = + content::ResourceRequestInfo::ForRequest(request); + return request_info && request_info->GetCustomCancelReason().as_string() == + safe_browsing::kCustomCancelReasonForURLLoader; } AwSafeBrowsingParallelResourceThrottle::AwSafeBrowsingParallelResourceThrottle(
diff --git a/android_webview/browser/aw_url_checker_delegate_impl.cc b/android_webview/browser/aw_url_checker_delegate_impl.cc index 15ed6df465..04b8625 100644 --- a/android_webview/browser/aw_url_checker_delegate_impl.cc +++ b/android_webview/browser/aw_url_checker_delegate_impl.cc
@@ -5,6 +5,7 @@ #include "android_webview/browser/aw_url_checker_delegate_impl.h" #include "android_webview/browser/aw_contents_client_bridge.h" +#include "android_webview/browser/aw_contents_io_thread_client.h" #include "android_webview/browser/aw_safe_browsing_ui_manager.h" #include "android_webview/browser/aw_safe_browsing_whitelist_manager.h" #include "android_webview/browser/net/aw_web_resource_request.h" @@ -56,8 +57,24 @@ bool AwUrlCheckerDelegateImpl::ShouldSkipRequestCheck( content::ResourceContext* resource_context, - const GURL& original_url) { - return false; + const GURL& original_url, + int frame_tree_node_id, + int render_process_id, + int render_frame_id, + bool originated_from_service_worker) { + std::unique_ptr<AwContentsIoThreadClient> client; + + if (originated_from_service_worker) + client = AwContentsIoThreadClient::GetServiceWorkerIoThreadClient(); + else if (render_process_id == -1 || render_frame_id == -1) { + client = AwContentsIoThreadClient::FromID(frame_tree_node_id); + } else { + client = + AwContentsIoThreadClient::FromID(render_process_id, render_frame_id); + } + + // Consider the request as whitelisted, if SafeBrowsing is not enabled. + return client && !client->GetSafeBrowsingEnabled(); } const safe_browsing::SBThreatTypeSet&
diff --git a/android_webview/browser/aw_url_checker_delegate_impl.h b/android_webview/browser/aw_url_checker_delegate_impl.h index 5746f0e..a7cabfeea 100644 --- a/android_webview/browser/aw_url_checker_delegate_impl.h +++ b/android_webview/browser/aw_url_checker_delegate_impl.h
@@ -45,7 +45,11 @@ bool has_user_gesture) override; bool IsUrlWhitelisted(const GURL& url) override; bool ShouldSkipRequestCheck(content::ResourceContext* resource_context, - const GURL& original_url) override; + const GURL& original_url, + int frame_tree_node_id, + int render_process_id, + int render_frame_id, + bool originated_from_service_worker) override; const safe_browsing::SBThreatTypeSet& GetThreatTypes() override; safe_browsing::SafeBrowsingDatabaseManager* GetDatabaseManager() override; safe_browsing::BaseUIManager* GetUIManager() override;
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc index 9202256d..b1496b2dd 100644 --- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -19,17 +19,20 @@ #include "android_webview/common/url_constants.h" #include "components/navigation_interception/intercept_navigation_delegate.h" #include "components/safe_browsing/android/safe_browsing_api_handler.h" +#include "components/safe_browsing/features.h" #include "components/web_restrictions/browser/web_restrictions_resource_throttle.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/resource_dispatcher_host_login_delegate.h" #include "content/public/browser/resource_request_info.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/browser_side_navigation_policy.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_status.h" +#include "services/network/public/cpp/features.h" #include "url/url_constants.h" using android_webview::AwContentsIoThreadClient; @@ -297,17 +300,26 @@ request); if (ioThreadThrottle->GetSafeBrowsingEnabled()) { - content::ResourceThrottle* throttle = - MaybeCreateAwSafeBrowsingResourceThrottle( - request, resource_type, - AwBrowserContext::GetDefault()->GetSafeBrowsingDBManager(), - AwBrowserContext::GetDefault()->GetSafeBrowsingUIManager(), - AwBrowserContext::GetDefault()->GetSafeBrowsingWhitelistManager()); - if (throttle == nullptr) { - // Should not happen - DLOG(WARNING) << "Failed creating safebrowsing throttle"; - } else { - throttles->push_back(base::WrapUnique(throttle)); + DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService)); + bool safe_browsing_url_loader_throttle_used = + base::FeatureList::IsEnabled( + safe_browsing::kCheckByURLLoaderThrottle) && + (!content::IsResourceTypeFrame(resource_type) || + content::IsNavigationMojoResponseEnabled()); + if (!safe_browsing_url_loader_throttle_used) { + content::ResourceThrottle* throttle = + MaybeCreateAwSafeBrowsingResourceThrottle( + request, resource_type, + AwBrowserContext::GetDefault()->GetSafeBrowsingDBManager(), + AwBrowserContext::GetDefault()->GetSafeBrowsingUIManager(), + AwBrowserContext::GetDefault() + ->GetSafeBrowsingWhitelistManager()); + if (throttle == nullptr) { + // Should not happen + DLOG(WARNING) << "Failed creating safebrowsing throttle"; + } else { + throttles->push_back(base::WrapUnique(throttle)); + } } }
diff --git a/android_webview/renderer/DEPS b/android_webview/renderer/DEPS index 6805730..833e166 100644 --- a/android_webview/renderer/DEPS +++ b/android_webview/renderer/DEPS
@@ -9,6 +9,7 @@ "+components/printing/common", "+components/printing/renderer", "+components/safe_browsing/common", + "+components/safe_browsing/features.h", "+components/safe_browsing/renderer", "+components/spellcheck/renderer", "+components/visitedlink/renderer",
diff --git a/android_webview/renderer/aw_url_loader_throttle_provider.cc b/android_webview/renderer/aw_url_loader_throttle_provider.cc index 2a5be521..aab8c4a 100644 --- a/android_webview/renderer/aw_url_loader_throttle_provider.cc +++ b/android_webview/renderer/aw_url_loader_throttle_provider.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/feature_list.h" +#include "components/safe_browsing/features.h" #include "components/safe_browsing/renderer/renderer_url_loader_throttle.h" #include "content/public/common/content_features.h" #include "content/public/common/service_names.mojom.h" @@ -21,7 +22,8 @@ : type_(type) { DETACH_FROM_THREAD(thread_checker_); - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { + if (base::FeatureList::IsEnabled(network::features::kNetworkService) || + base::FeatureList::IsEnabled(safe_browsing::kCheckByURLLoaderThrottle)) { content::RenderThread::Get()->GetConnector()->BindInterface( content::mojom::kBrowserServiceName, mojo::MakeRequest(&safe_browsing_info_)); @@ -50,7 +52,10 @@ DCHECK(!is_frame_resource || type_ == content::URLLoaderThrottleProviderType::kFrame); - if (network_service_enabled && !is_frame_resource) { + if ((network_service_enabled || + base::FeatureList::IsEnabled( + safe_browsing::kCheckByURLLoaderThrottle)) && + !is_frame_resource) { if (safe_browsing_info_) safe_browsing_.Bind(std::move(safe_browsing_info_)); throttles.push_back(
diff --git a/ash/app_list/model/search/search_model.cc b/ash/app_list/model/search/search_model.cc index 6c0ee945..a9283135 100644 --- a/ash/app_list/model/search/search_model.cc +++ b/ash/app_list/model/search/search_model.cc
@@ -90,4 +90,12 @@ // Any remaining results in |results_map| will be automatically deleted. } +SearchResult* SearchModel::FindSearchResult(const std::string& id) { + for (const auto& result : *results_) { + if (result->id() == id) + return result.get(); + } + return nullptr; +} + } // namespace app_list
diff --git a/ash/app_list/model/search/search_model.h b/ash/app_list/model/search/search_model.h index fb62bc2c..6b87b63 100644 --- a/ash/app_list/model/search/search_model.h +++ b/ash/app_list/model/search/search_model.h
@@ -6,6 +6,7 @@ #define ASH_APP_LIST_MODEL_SEARCH_SEARCH_MODEL_H_ #include <memory> +#include <string> #include <vector> #include "ash/app_list/model/app_list_model_export.h" @@ -48,6 +49,8 @@ void PublishResults(std::vector<std::unique_ptr<SearchResult>> new_results); + SearchResult* FindSearchResult(const std::string& id); + private: std::unique_ptr<SearchBoxModel> search_box_; std::unique_ptr<SearchResults> results_;
diff --git a/ash/session/session_controller.cc b/ash/session/session_controller.cc index 101897d..50ca467 100644 --- a/ash/session/session_controller.cc +++ b/ash/session/session_controller.cc
@@ -174,6 +174,14 @@ active_user_type == user_manager::USER_TYPE_CHILD; } +bool SessionController::IsUserLegacySupervised() const { + if (!IsActiveUserSessionStarted()) + return false; + + user_manager::UserType active_user_type = GetUserSession(0)->user_info->type; + return active_user_type == user_manager::USER_TYPE_SUPERVISED; +} + bool SessionController::IsUserChild() const { if (!IsActiveUserSessionStarted()) return false;
diff --git a/ash/session/session_controller.h b/ash/session/session_controller.h index 551e0d9b..9cdba9e 100644 --- a/ash/session/session_controller.h +++ b/ash/session/session_controller.h
@@ -106,6 +106,9 @@ // account or kid account. bool IsUserSupervised() const; + // Returns true if the current user is legacy supervised. + bool IsUserLegacySupervised() const; + // Returns true if the current user is a child account. bool IsUserChild() const;
diff --git a/ash/shelf/login_shelf_view.cc b/ash/shelf/login_shelf_view.cc index c0fb6ec9..899927c 100644 --- a/ash/shelf/login_shelf_view.cc +++ b/ash/shelf/login_shelf_view.cc
@@ -35,6 +35,7 @@ #include "ui/gfx/paint_vector_icon.h" #include "ui/views/accessibility/ax_aura_obj_cache.h" #include "ui/views/animation/ink_drop_impl.h" +#include "ui/views/animation/ink_drop_mask.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/focus/focus_search.h" #include "ui/views/layout/box_layout.h" @@ -84,7 +85,8 @@ SetFocusBehavior(FocusBehavior::ALWAYS); SetFocusPainter(views::Painter::CreateSolidFocusPainter( kFocusBorderColor, kFocusBorderThickness, gfx::InsetsF())); - SetInkDropMode(views::InkDropHostView::InkDropMode::ON); + SetInkDropMode(InkDropMode::ON); + set_has_ink_drop_action_on_click(true); set_ink_drop_base_color(kShelfInkDropBaseColor); set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity); SetTextSubpixelRenderingEnabled(false); @@ -112,6 +114,11 @@ ink_drop->SetShowHighlightOnFocus(false); return std::move(ink_drop); } + std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override { + gfx::InsetsF insets(ash::kHitRegionPadding, ash::kHitRegionPadding); + return std::make_unique<views::RoundRectInkDropMask>( + size(), insets, kTrayRoundedBorderRadius); + } private: DISALLOW_COPY_AND_ASSIGN(LoginShelfButton);
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc index 75c3f58..229a3b65 100644 --- a/ash/shell/app_list.cc +++ b/ash/shell/app_list.cc
@@ -227,14 +227,15 @@ return search_model_.get(); } - void OpenSearchResult(app_list::SearchResult* result, + void OpenSearchResult(const std::string& result_id, int event_flags) override { const ExampleSearchResult* example_result = - static_cast<const ExampleSearchResult*>(result); + static_cast<const ExampleSearchResult*>( + search_model_->FindSearchResult(result_id)); WindowTypeShelfItem::ActivateItem(example_result->type(), event_flags); } - void InvokeSearchResultAction(app_list::SearchResult* result, + void InvokeSearchResultAction(const std::string& result_id, int action_index, int event_flags) override { NOTIMPLEMENTED(); @@ -263,7 +264,7 @@ } } - void ViewShown() override { + void ViewShown(int64_t display_id) override { // Nothing needs to be done. }
diff --git a/ash/system/tray/system_tray_bubble.cc b/ash/system/tray/system_tray_bubble.cc index b6b6fcc8..35ebb8d 100644 --- a/ash/system/tray/system_tray_bubble.cc +++ b/ash/system/tray/system_tray_bubble.cc
@@ -142,7 +142,14 @@ } UpdateBottomPadding(); + + // Enfore relayout of |bubble_view_|. The view code will skip the relayout of + // |bubble_view_| if its bounds does not change. However, we need to + // force |bubble_view_| relayout in order to set the bounds of its newly + // created children view to preferred sizes. + bubble_view_->InvalidateLayout(); bubble_view_->GetWidget()->GetContentsView()->Layout(); + // Make sure that the bubble is large enough for the default view. if (system_tray_type == SystemTrayView::SYSTEM_TRAY_TYPE_DEFAULT) { bubble_view_->SetMaxHeight(0); // Clear max height limit.
diff --git a/ash/system/user/user_card_view.cc b/ash/system/user/user_card_view.cc index 2cd529d..7748a06 100644 --- a/ash/system/user/user_card_view.cc +++ b/ash/system/user/user_card_view.cc
@@ -400,7 +400,7 @@ base::string16 user_email_string; if (!is_guest) { user_email_string = - Shell::Get()->session_controller()->IsUserSupervised() + Shell::Get()->session_controller()->IsUserLegacySupervised() ? l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SUPERVISED_LABEL) : base::UTF8ToUTF16(user_session->user_info->display_email); }
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index 0e11892..29628c1 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -8,7 +8,6 @@ #include <memory> #include "ash/display/screen_orientation_controller_chromeos.h" -#include "ash/public/cpp/app_types.h" #include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/screen_util.h" @@ -27,10 +26,8 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/optional.h" -#include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" -#include "ui/base/class_property.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" #include "ui/views/widget/widget.h" @@ -105,16 +102,6 @@ } bool SplitViewController::CanSnap(aura::Window* window) { - // In M65, some ARC apps can be freely resized and thus are capble of - // displaying in splitscreen, but splitscreen is not supported for ARC apps - // windows yet in M65, thus we should explicity return false here for ARC apps - // windows. Otherwise we may see issues as in https://crbug.com/808748. It - // will be reverted later in M66. - if (window->GetProperty(aura::client::kAppType) == - static_cast<int>(AppType::ARC_APP)) { - return false; - } - if (!wm::CanActivateWindow(window)) return false; if (!wm::GetWindowState(window)->CanSnap())
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc b/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc index 918e493..3ae508d 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc
@@ -21,6 +21,7 @@ #include "ash/wm/switchable_windows.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_properties.h" +#include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" #include "ash/wm/window_state_observer.h" #include "ash/wm/window_util.h" @@ -1515,8 +1516,6 @@ EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized()); EXPECT_EQ(rect1.ToString(), w1->bounds().ToString()); EXPECT_EQ(rect2.ToString(), w2->bounds().ToString()); - EXPECT_TRUE(wm::GetWindowState(w1.get())->can_be_dragged()); - EXPECT_TRUE(wm::GetWindowState(w2.get())->can_be_dragged()); // Enter tablet mode. Neither window should be managed because they have // the always-on-top property set, which means that none of their properties @@ -1528,8 +1527,6 @@ EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized()); EXPECT_EQ(rect1.ToString(), w1->bounds().ToString()); EXPECT_EQ(rect2.ToString(), w2->bounds().ToString()); - EXPECT_TRUE(wm::GetWindowState(w1.get())->can_be_dragged()); - EXPECT_TRUE(wm::GetWindowState(w2.get())->can_be_dragged()); // Remove the always-on-top property from both windows while in maximize // mode. The windows should become managed, which means they should be @@ -1543,8 +1540,6 @@ EXPECT_NE(rect1.size().ToString(), w1->bounds().size().ToString()); EXPECT_NE(rect2.origin().ToString(), w2->bounds().origin().ToString()); EXPECT_EQ(rect2.size().ToString(), w2->bounds().size().ToString()); - EXPECT_FALSE(wm::GetWindowState(w1.get())->can_be_dragged()); - EXPECT_FALSE(wm::GetWindowState(w2.get())->can_be_dragged()); // Applying the always-on-top property to both windows while in maximize // mode should cause both windows to return to their original size, @@ -1556,8 +1551,6 @@ EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized()); EXPECT_EQ(rect1.ToString(), w1->bounds().ToString()); EXPECT_EQ(rect2.ToString(), w2->bounds().ToString()); - EXPECT_TRUE(wm::GetWindowState(w1.get())->can_be_dragged()); - EXPECT_TRUE(wm::GetWindowState(w2.get())->can_be_dragged()); // The always-on-top windows should not change when leaving tablet mode. DestroyTabletModeWindowManager(); @@ -1565,8 +1558,6 @@ EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized()); EXPECT_EQ(rect1.ToString(), w1->bounds().ToString()); EXPECT_EQ(rect2.ToString(), w2->bounds().ToString()); - EXPECT_TRUE(wm::GetWindowState(w1.get())->can_be_dragged()); - EXPECT_TRUE(wm::GetWindowState(w2.get())->can_be_dragged()); } // Tests that windows that can control maximized bounds are not maximized @@ -1717,4 +1708,20 @@ window->Show(); } +// Test that there is no window resizer in tablet mode. +TEST_F(TabletModeWindowManagerTest, NoWindowResizerInTabletMode) { + gfx::Rect rect(10, 10, 200, 200); + std::unique_ptr<aura::Window> window( + CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect)); + std::unique_ptr<WindowResizer> resizer(CreateWindowResizer( + window.get(), gfx::Point(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE)); + EXPECT_TRUE(resizer.get()); + resizer.reset(); + + CreateTabletModeWindowManager(); + resizer = CreateWindowResizer(window.get(), gfx::Point(), HTCAPTION, + ::wm::WINDOW_MOVE_SOURCE_MOUSE); + EXPECT_FALSE(resizer.get()); +} + } // namespace ash
diff --git a/ash/wm/tablet_mode/tablet_mode_window_state.cc b/ash/wm/tablet_mode/tablet_mode_window_state.cc index bd89cb7..8fab2dd 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_state.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_state.cc
@@ -296,15 +296,12 @@ UpdateWindow(window_state, GetMaximizedOrCenteredWindowType(window_state), true /* animated */); } - - window_state->set_can_be_dragged(false); } void TabletModeWindowState::DetachState(wm::WindowState* window_state) { // From now on, we can use the default session restore mechanism again. SetWindowRestoreOverrides(window_state->window(), gfx::Rect(), ui::SHOW_STATE_NORMAL); - window_state->set_can_be_dragged(true); } void TabletModeWindowState::UpdateWindow(wm::WindowState* window_state,
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 7712c98..aa5291a 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -479,7 +479,6 @@ hide_shelf_when_fullscreen_(true), autohide_shelf_when_maximized_or_fullscreen_(false), minimum_visibility_(false), - can_be_dragged_(true), cached_always_on_top_(false), ignore_property_change_(false), current_state_(new DefaultState(ToWindowStateType(GetShowState()))) {
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index b745ac3..16ba013 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h
@@ -236,12 +236,6 @@ minimum_visibility_ = minimum_visibility; } - // Specifies if the window can be dragged by the user via the caption or not. - bool can_be_dragged() const { return can_be_dragged_; } - void set_can_be_dragged(bool can_be_dragged) { - can_be_dragged_ = can_be_dragged; - } - // Gets/Sets the bounds of the window before it was moved by the auto window // management. As long as it was not auto-managed, it will return NULL. base::Optional<gfx::Rect> pre_auto_manage_window_bounds() const { @@ -415,7 +409,6 @@ bool hide_shelf_when_fullscreen_; bool autohide_shelf_when_maximized_or_fullscreen_; bool minimum_visibility_; - bool can_be_dragged_; bool cached_always_on_top_; bool allow_set_bounds_direct_ = false;
diff --git a/ash/wm/wm_toplevel_window_event_handler.cc b/ash/wm/wm_toplevel_window_event_handler.cc index c83677c..517ae7f 100644 --- a/ash/wm/wm_toplevel_window_event_handler.cc +++ b/ash/wm/wm_toplevel_window_event_handler.cc
@@ -7,6 +7,7 @@ #include "ash/public/cpp/config.h" #include "ash/shell.h" #include "ash/wm/resize_shadow_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" #include "ash/wm/window_state_observer.h" @@ -63,8 +64,13 @@ // TODO: http://crbug.com/640773. return; } - if (!wm::GetWindowState(window)->can_be_dragged()) + + // Window resize in tablet mode is disabled (except in splitscreen). + if (Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled()) { return; + } ResizeShadowController* resize_shadow_controller = Shell::Get()->resize_shadow_controller(); @@ -77,8 +83,6 @@ // TODO: http://crbug.com/640773. return; } - if (!wm::GetWindowState(window)->can_be_dragged()) - return; ResizeShadowController* resize_shadow_controller = Shell::Get()->resize_shadow_controller();
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index bd46183a..2746cae 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -17,6 +17,7 @@ #include "ash/shell_port.h" #include "ash/wm/default_window_resizer.h" #include "ash/wm/panels/panel_window_resizer.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_state.h" #include "ash/wm/wm_event.h" @@ -50,8 +51,12 @@ return nullptr; } - if (!window_state->can_be_dragged()) + // Window resize in tablet mode is disabled (except in splitscreen). + if (Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled()) { return nullptr; + } // TODO(varkha): The chaining of window resizers causes some of the logic // to be repeated and the logic flow difficult to control. With some windows
diff --git a/base/BUILD.gn b/base/BUILD.gn index c4f703b..1084ddab 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2903,7 +2903,6 @@ ":base_junit_test_support", "//third_party/hamcrest:hamcrest_java", ] - srcjar_deps = [ ":base_build_config_gen" ] } java_cpp_enum("base_android_java_enums_srcjar") { @@ -2917,19 +2916,8 @@ ] } - java_cpp_template("base_build_config_gen") { - sources = [ - "android/java/templates/BuildConfig.template", - ] - package_path = "org/chromium/base" - - defines = [] - if (is_java_debug || dcheck_always_on) { - defines += [ "_DCHECK_IS_ON" ] - } - if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) { - defines += [ "_IS_UBSAN" ] - } + generate_build_config_srcjar("base_build_config_gen") { + use_final_fields = false } java_cpp_template("base_native_libraries_gen") {
diff --git a/base/allocator/partition_allocator/address_space_randomization_unittest.cc b/base/allocator/partition_allocator/address_space_randomization_unittest.cc index 4d6aa794..40f494d 100644 --- a/base/allocator/partition_allocator/address_space_randomization_unittest.cc +++ b/base/allocator/partition_allocator/address_space_randomization_unittest.cc
@@ -131,6 +131,10 @@ // Test for correlations between recent bits from the PRNG, or bits that are // biased. void RandomBitCorrelation(int random_bit) { + uintptr_t mask = GetMask(); + if ((mask & (1ULL << random_bit)) == 0) + return; // bit is always 0. + #ifdef DEBUG constexpr int kHistory = 2; constexpr int kRepeats = 1000; @@ -187,22 +191,54 @@ } } -// TODO(crbug.com/809367): Flaky on Linux TSAN. -#if defined(OS_LINUX) && defined(THREAD_SANITIZER) -#define MAYBE_Random DISABLED_Random -#else -#define MAYBE_Random Random -#endif -TEST(AddressSpaceRandomizationTest, MAYBE_Random) { - uintptr_t mask = GetMask(); - if (!mask) - return; - // Use the mask to determine which bits to test. - for (int i = 0; mask != 0; mask >>= 1, i++) { - if ((mask & 0x1) == 0) - continue; - RandomBitCorrelation(i); +// Tests are fairly slow, so give each random bit its own test. +#define TEST_RANDOM_BIT(BIT) \ + TEST(AddressSpaceRandomizationTest, RandomBitCorrelations##BIT) { \ + RandomBitCorrelation(BIT); \ } -} + +// The first 12 bits on all platforms are always 0. +TEST_RANDOM_BIT(12) +TEST_RANDOM_BIT(13) +TEST_RANDOM_BIT(14) +TEST_RANDOM_BIT(15) +TEST_RANDOM_BIT(16) +TEST_RANDOM_BIT(17) +TEST_RANDOM_BIT(18) +TEST_RANDOM_BIT(19) +TEST_RANDOM_BIT(20) +TEST_RANDOM_BIT(21) +TEST_RANDOM_BIT(22) +TEST_RANDOM_BIT(23) +TEST_RANDOM_BIT(24) +TEST_RANDOM_BIT(25) +TEST_RANDOM_BIT(26) +TEST_RANDOM_BIT(27) +TEST_RANDOM_BIT(28) +TEST_RANDOM_BIT(29) +TEST_RANDOM_BIT(30) +TEST_RANDOM_BIT(31) +#if defined(ARCH_CPU_64_BITS) +TEST_RANDOM_BIT(32) +TEST_RANDOM_BIT(33) +TEST_RANDOM_BIT(34) +TEST_RANDOM_BIT(35) +TEST_RANDOM_BIT(36) +TEST_RANDOM_BIT(37) +TEST_RANDOM_BIT(38) +TEST_RANDOM_BIT(39) +TEST_RANDOM_BIT(40) +TEST_RANDOM_BIT(41) +TEST_RANDOM_BIT(42) +TEST_RANDOM_BIT(43) +TEST_RANDOM_BIT(44) +TEST_RANDOM_BIT(45) +TEST_RANDOM_BIT(46) +TEST_RANDOM_BIT(47) +TEST_RANDOM_BIT(48) +// No platforms have more than 48 address bits. +#endif // defined(ARCH_CPU_64_BITS) + +#undef TEST_RANDOM_BIT } // namespace base
diff --git a/base/android/build_info.cc b/base/android/build_info.cc index 7dd4291..709c545 100644 --- a/base/android/build_info.cc +++ b/base/android/build_info.cc
@@ -69,7 +69,8 @@ gms_version_code_(StrDupParam(params, 12)), installer_package_name_(StrDupParam(params, 13)), abi_name_(StrDupParam(params, 14)), - extracted_file_suffix_(params[15]), + firebase_app_id_(StrDupParam(params, 15)), + extracted_file_suffix_(params[16]), java_exception_info_(NULL) {} // static
diff --git a/base/android/build_info.h b/base/android/build_info.h index 52aec78..e8cf555e 100644 --- a/base/android/build_info.h +++ b/base/android/build_info.h
@@ -98,6 +98,9 @@ return package_name_; } + // Will be empty string if no app id is assigned. + const char* firebase_app_id() const { return firebase_app_id_; } + const char* build_type() const { return build_type_; } @@ -144,6 +147,7 @@ const char* const gms_version_code_; const char* const installer_package_name_; const char* const abi_name_; + const char* const firebase_app_id_; // Not needed by breakpad. const std::string extracted_file_suffix_; // This is set via set_java_exception_info, not at constructor time.
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java index 89fee626..6b6cfa8 100644 --- a/base/android/java/src/org/chromium/base/BuildInfo.java +++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -73,7 +73,8 @@ Build.BRAND, Build.DEVICE, Build.ID, Build.MANUFACTURER, Build.MODEL, String.valueOf(Build.VERSION.SDK_INT), Build.TYPE, packageLabel, packageName, versionCode, versionName, getAndroidBuildFingerprint(), getGMSVersionCode(pm), - installerPackageName, abiString, extractedFileSuffix, + installerPackageName, abiString, BuildConfig.FIREBASE_APP_ID, + extractedFileSuffix, }; } catch (NameNotFoundException e) { throw new RuntimeException(e); @@ -107,7 +108,7 @@ /** Returns a string that is different each time the apk changes. */ public static String getExtractedFileSuffix() { - return getAll()[15]; + return getAll()[16]; } public static String getPackageLabel() {
diff --git a/base/android/java/templates/BuildConfig.template b/base/android/java/templates/BuildConfig.template index 6b63584..8d6f440 100644 --- a/base/android/java/templates/BuildConfig.template +++ b/base/android/java/templates/BuildConfig.template
@@ -4,6 +4,15 @@ package org.chromium.base; +#define Q(x) #x +#define QUOTE(x) Q(x) + +#if defined(USE_FINAL) +#define MAYBE_FINAL final +#else +#define MAYBE_FINAL +#endif + /** * Build configuration. Generated on a per-target basis. */ @@ -22,34 +31,37 @@ #endif } - // DCHECK_IS_ON does not change between targets, can be final and optimized out. -#if defined(_DCHECK_IS_ON) - public static final boolean DCHECK_IS_ON = true; +#if defined(_FIREBASE_APP_ID) + public static MAYBE_FINAL String FIREBASE_APP_ID = QUOTE(_FIREBASE_APP_ID); #else - public static final boolean DCHECK_IS_ON = false; + public static MAYBE_FINAL String FIREBASE_APP_ID = ""; +#endif + +#if defined(_DCHECK_IS_ON) + public static MAYBE_FINAL boolean DCHECK_IS_ON = true; +#else + public static MAYBE_FINAL boolean DCHECK_IS_ON = false; #endif #if defined(_IS_UBSAN) - public static final boolean IS_UBSAN = true; + public static MAYBE_FINAL boolean IS_UBSAN = true; #else - public static final boolean IS_UBSAN = false; + public static MAYBE_FINAL boolean IS_UBSAN = false; #endif // Sorted list of locales that have a compressed .pak within assets. // Stored as an array because AssetManager.list() is slow. - public static final String[] COMPRESSED_LOCALES = #if defined(COMPRESSED_LOCALE_LIST) - COMPRESSED_LOCALE_LIST; + public static MAYBE_FINAL String[] COMPRESSED_LOCALES = COMPRESSED_LOCALE_LIST; #else - {}; + public static MAYBE_FINAL String[] COMPRESSED_LOCALES = {}; #endif // Sorted list of locales that have an uncompressed .pak within assets. // Stored as an array because AssetManager.list() is slow. - public static final String[] UNCOMPRESSED_LOCALES = #if defined(UNCOMPRESSED_LOCALE_LIST) - UNCOMPRESSED_LOCALE_LIST; + public static MAYBE_FINAL String[] UNCOMPRESSED_LOCALES = UNCOMPRESSED_LOCALE_LIST; #else - {}; + public static MAYBE_FINAL String[] UNCOMPRESSED_LOCALES = {}; #endif }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/RetryOnFailure.java b/base/test/android/javatests/src/org/chromium/base/test/util/RetryOnFailure.java index f96bf53..eb98008 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/util/RetryOnFailure.java +++ b/base/test/android/javatests/src/org/chromium/base/test/util/RetryOnFailure.java
@@ -9,8 +9,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -// Note this annotation may not do anything yet. Check crbug.com/619055 -// for latest status. +// Note this annotation may be a NOOP. Check http://crbug.com/797002 for latest status (also see +// http://crbug.com/619055). Current default behavior is to retry all tests on failure. /** * Mark a test as flaky and should be retried on failure. The test is * considered passed by the test script if any retry succeeds.
diff --git a/build/android/gradle/root.jinja b/build/android/gradle/root.jinja index ac31315..178d551 100644 --- a/build/android/gradle/root.jinja +++ b/build/android/gradle/root.jinja
@@ -12,7 +12,7 @@ } dependencies { {% if canary %} - classpath "com.android.tools.build:gradle:3.1.0-alpha08" + classpath "com.android.tools.build:gradle:3.1.0-beta1" {% else %} classpath "com.android.tools.build:gradle:3.0.1" {% endif %}
diff --git a/build/android/lighttpd_server.py b/build/android/lighttpd_server.py index 15bc9969..89a828a 100755 --- a/build/android/lighttpd_server.py +++ b/build/android/lighttpd_server.py
@@ -93,6 +93,7 @@ 'Could not find lighttpd at %s.\n' 'It may need to be installed (e.g. sudo apt-get install lighttpd)' % self.lighttpd_path) + # pylint: disable=no-member self.process = pexpect.spawn(self.lighttpd_path, ['-D', '-f', self.config_path, '-m', self.lighttpd_module_path], @@ -137,6 +138,7 @@ except (httplib.HTTPException, socket.error) as client_error: pass # Probably too quick connecting: try again # Check for server startup error messages + # pylint: disable=no-member ix = self.process.expect([pexpect.TIMEOUT, pexpect.EOF, '.+'], timeout=timeout) if ix == 2: # stdout spew from the server
diff --git a/build/android/pylib/constants/__init__.py b/build/android/pylib/constants/__init__.py index e844a1ad..f100211b 100644 --- a/build/android/pylib/constants/__init__.py +++ b/build/android/pylib/constants/__init__.py
@@ -96,7 +96,7 @@ SCREENSHOTS_DIR = os.path.join(DIR_SOURCE_ROOT, 'out_screenshots') ANDROID_SDK_VERSION = version_codes.O_MR1 -ANDROID_SDK_BUILD_TOOLS_VERSION = '27.0.1' +ANDROID_SDK_BUILD_TOOLS_VERSION = '27.0.3' ANDROID_SDK_ROOT = os.path.join(DIR_SOURCE_ROOT, 'third_party', 'android_tools', 'sdk') ANDROID_SDK_TOOLS = os.path.join(ANDROID_SDK_ROOT,
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index 1a90862..e4002393 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -68,7 +68,7 @@ if (android_sdk_release == "o_mr1") { default_android_sdk_root = "//third_party/android_tools/sdk" default_android_sdk_version = "27" - default_android_sdk_build_tools_version = "27.0.1" + default_android_sdk_build_tools_version = "27.0.3" default_android_sdk_tools_version_suffix = "-26.0.0-dev" public_android_sdk = true }
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 58274a1..9661d61 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1181,7 +1181,12 @@ if (!defined(srcjar_deps)) { srcjar_deps = [] } - srcjar_deps += [ ":$_process_resources_target" ] + srcjar_deps += [ + ":$_process_resources_target", + + # This dep is required for any targets that depend on //base:base_java. + "//base:base_build_config_gen", + ] } test_runner_script(_test_runner_target_name) { @@ -1649,6 +1654,64 @@ } } + # Creates org/chromium/base/BuildConfig.java + # This doesn't really belong in //build since it genates a file for //base. + # However, we don't currently have a better way to include this file in all + # apks that depend on //base:base_java. + # + # Variables: + # use_final_fields: True to use final fields. All other variables are + # ignored when this is false. + # build_config: Path to build_config used for locale list + # enable_multidex: Value for ENABLE_MULTIDEX. + # firebase_app_id: Value for FIREBASE_APP_ID. + # + template("generate_build_config_srcjar") { + java_cpp_template(target_name) { + package_path = "org/chromium/base" + sources = [ + "//base/android/java/templates/BuildConfig.template", + ] + defines = [] + + # TODO(agrieve): These two are not target-specific and should be moved + # to BuildHooks.java. + # Set these even when !use_final_fields so that they have correct default + # values withnin junit_binary(). + if (is_java_debug || dcheck_always_on) { + defines += [ "_DCHECK_IS_ON" ] + } + if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) { + defines += [ "_IS_UBSAN" ] + } + + if (invoker.use_final_fields) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + defines += [ "USE_FINAL" ] + if (invoker.enable_multidex) { + defines += [ "ENABLE_MULTIDEX" ] + } + inputs = [ + invoker.build_config, + ] + _rebased_build_config = rebase_path(invoker.build_config) + defines += [ + "COMPRESSED_LOCALE_LIST=" + + "@FileArg($_rebased_build_config:compressed_locales_java_list)", + "UNCOMPRESSED_LOCALE_LIST=" + + "@FileArg($_rebased_build_config:uncompressed_locales_java_list)", + ] + if (defined(invoker.firebase_app_id)) { + defines += [ "_FIREBASE_APP_ID=${invoker.firebase_app_id}" ] + } + } + } + } + # Declare an Android apk target # # This target creates an Android APK containing java code, resources, assets, @@ -1688,6 +1751,8 @@ # generate_buildconfig_java: If defined and false, skip generating the # BuildConfig java class describing the build configuration. The default # is true for non-test APKs. + # firebase_app_id: The value for BuildConfig.FIREBASE_APP_ID (optional). + # Identifier is sent with crash reports to enable Java stack deobfuscation. # requires_sdk_api_level_23: If defined and true, the apk is intended for # installation only on Android M or later. In these releases the system # linker does relocation unpacking, so we can enable it unconditionally. @@ -2104,31 +2169,14 @@ } if (_generate_buildconfig_java) { - java_cpp_template("${_template_name}__build_config_java") { - package_path = "org/chromium/base" - sources = [ - "//base/android/java/templates/BuildConfig.template", - ] + generate_build_config_srcjar("${_template_name}__build_config_java") { + forward_variables_from(invoker, [ "firebase_app_id" ]) + use_final_fields = true + build_config = _build_config + enable_multidex = _enable_multidex deps = [ ":$_build_config_target", ] - - defines = [] - if (_enable_multidex) { - defines += [ "ENABLE_MULTIDEX" ] - } - if (is_java_debug || dcheck_always_on) { - defines += [ "_DCHECK_IS_ON" ] - } - if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) { - defines += [ "_IS_UBSAN" ] - } - defines += [ - "COMPRESSED_LOCALE_LIST=" + - "@FileArg($_rebased_build_config:compressed_locales_java_list)", - "UNCOMPRESSED_LOCALE_LIST=" + - "@FileArg($_rebased_build_config:uncompressed_locales_java_list)", - ] } _srcjar_deps += [ ":${_template_name}__build_config_java" ] }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 58cf167..bccab9b8 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1442,8 +1442,7 @@ # Warn on missing break statements at the end of switch cases. # For intentional fallthrough, use FALLTHROUGH; from base/compiler_specific.h - # TODO(thakis): Enable for all platforms, https://crbug.com/177475 - if (is_clang && !is_mac && !is_ios) { + if (is_clang) { cflags += [ "-Wimplicit-fallthrough" ] }
diff --git a/build/dotfile_settings.gni b/build/dotfile_settings.gni index 4afdbf80..8382c75 100644 --- a/build/dotfile_settings.gni +++ b/build/dotfile_settings.gni
@@ -24,6 +24,7 @@ "//build/config/sysroot.gni", "//build/config/win/BUILD.gn", "//build/config/win/visual_studio_version.gni", + "//build/toolchain/BUILD.gn", "//build/toolchain/concurrent_links.gni", "//build/toolchain/mac/BUILD.gn", "//build/toolchain/nacl/BUILD.gn",
diff --git a/build/fuchsia/exe_runner.py b/build/fuchsia/exe_runner.py index 7fde4db..25ee738 100755 --- a/build/fuchsia/exe_runner.py +++ b/build/fuchsia/exe_runner.py
@@ -53,7 +53,8 @@ return 2 return RunFuchsia(bootfs, args.device, args.kernel, args.dry_run, - forward_ssh_port=args.forward_ssh_port) + forward_ssh_port=args.forward_ssh_port, + vm_cpu_cores=args.vm_cpu_cores) if __name__ == '__main__':
diff --git a/build/fuchsia/runner_common.py b/build/fuchsia/runner_common.py index 56d0284..e64a9fcf 100755 --- a/build/fuchsia/runner_common.py +++ b/build/fuchsia/runner_common.py
@@ -218,6 +218,9 @@ 'one from the SDK') parser.add_argument('--device', '-d', action='store_true', default=False, help='Run on hardware device instead of QEMU.') + parser.add_argument('--vm-cpu-cores', type=int, default=4, + help='Sets the number of CPU cores to provide if ' + 'launching in a VM with QEMU.') parser.add_argument('--dry-run', '-n', action='store_true', default=False, help='Just print commands, don\'t execute them.') parser.add_argument('--kernel', type=os.path.realpath, @@ -620,7 +623,8 @@ def RunFuchsia(bootfs_data, use_device, kernel_path, dry_run, - test_launcher_summary_output=None, forward_ssh_port=None): + test_launcher_summary_output=None, forward_ssh_port=None, + vm_cpu_cores=4): if not kernel_path: # TODO(wez): Parameterize this on the |target_cpu| from GN. kernel_path = os.path.join(_TargetCpuToSdkBinPath(bootfs_data.target_cpu), @@ -662,7 +666,7 @@ '-nographic', '-kernel', kernel_path, '-initrd', bootfs_data.bootfs, - '-smp', '4', + '-smp', str(vm_cpu_cores), # Use stdio for the guest OS only; don't attach the QEMU interactive # monitor.
diff --git a/build/fuchsia/test_runner.py b/build/fuchsia/test_runner.py index d69f039..42506be 100755 --- a/build/fuchsia/test_runner.py +++ b/build/fuchsia/test_runner.py
@@ -24,10 +24,6 @@ sys.path.append(os.path.join(DIR_SOURCE_ROOT, 'build', 'util', 'lib', 'common')) import chrome_test_server_spawner -# RunFuchsia() may run qemu with 1 or 4 CPUs. In both cases keep test -# concurrency set to 4. -DEFAULT_TEST_CONCURRENCY = 4 - def IsLocalPortAvailable(port): s = socket.socket() @@ -132,8 +128,11 @@ child_args.append('--test-launcher-batch-limit=%d' % args.test_launcher_batch_limit) + # By default run the same number of test jobs as there are CPU cores. + # If running tests on a device then the caller should provide the + # test-launcher-jobs limit explicitly, since we can't count the CPU cores. test_concurrency = args.test_launcher_jobs \ - if args.test_launcher_jobs else DEFAULT_TEST_CONCURRENCY + if args.test_launcher_jobs else args.vm_cpu_cores child_args.append('--test-launcher-jobs=%d' % test_concurrency) if args.gtest_filter: @@ -210,7 +209,8 @@ return RunFuchsia(bootfs, args.device, args.kernel, args.dry_run, test_launcher_summary_output= - args.test_launcher_summary_output) + args.test_launcher_summary_output, + vm_cpu_cores = args.vm_cpu_cores) finally: # Stop the spawner to make sure it doesn't leave testserver running, in # case some tests failed.
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh index 172aa9c..f82cc26f 100755 --- a/build/install-build-deps.sh +++ b/build/install-build-deps.sh
@@ -160,6 +160,8 @@ git-core git-svn gperf + libappindicator-dev + libappindicator3-dev libasound2-dev libbrlapi-dev libav-tools @@ -227,9 +229,11 @@ # Full list of required run-time libraries lib_list="\ + libappindicator1 + libappindicator3-1 + libasound2 libatk1.0-0 libc6 - libasound2 libcairo2 libcap2 libcups2
diff --git a/build/linux/sysroot_scripts/packagelist.stretch.amd64 b/build/linux/sysroot_scripts/packagelist.stretch.amd64 index aac388b..9579446 100644 --- a/build/linux/sysroot_scripts/packagelist.stretch.amd64 +++ b/build/linux/sysroot_scripts/packagelist.stretch.amd64
@@ -75,12 +75,20 @@ http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-3_1.15-1+deb9u1_amd64.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-dev_1.15-1+deb9u1_amd64.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5support0_1.15-1+deb9u1_amd64.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator1_0.4.92-4_amd64.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-1_0.4.92-4_amd64.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-dev_0.4.92-4_amd64.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator-dev_0.4.92-4_amd64.deb http://ftp.us.debian.org/debian/pool/main/liba/libasyncns/libasyncns0_0.8-6_amd64.deb http://ftp.us.debian.org/debian/pool/main/libb/libbsd/libbsd0_0.8.3-1_amd64.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap2_2.25-1_amd64.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap-dev_2.25-1_amd64.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap-ng/libcap-ng0_0.7.7-3+b1_amd64.deb http://ftp.us.debian.org/debian/pool/main/libd/libdatrie/libdatrie1_0.2.10-4+b1_amd64.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib4_12.10.2-2_amd64.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib-dev_12.10.2-2_amd64.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk3-4_12.10.2-2_amd64.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk4_12.10.2-2_amd64.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm2_2.4.74-1_amd64.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-amdgpu1_2.4.74-1_amd64.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-dev_2.4.74-1_amd64.deb @@ -98,6 +106,8 @@ http://ftp.us.debian.org/debian/pool/main/libi/libice/libice6_1.0.9-2_amd64.deb http://ftp.us.debian.org/debian/pool/main/libi/libidl/libidl-2-0_0.8.14-4_amd64.deb http://ftp.us.debian.org/debian/pool/main/libi/libidn/libidn11_1.33-1_amd64.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator3-7_0.5.0-3+b1_amd64.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator7_0.5.0-3+b1_amd64.deb http://ftp.us.debian.org/debian/pool/main/libj/libjpeg-turbo/libjpeg62-turbo_1.5.1-2_amd64.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp1_1.7.4-3_amd64.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp-dev_1.7.4-3_amd64.deb
diff --git a/build/linux/sysroot_scripts/packagelist.stretch.arm b/build/linux/sysroot_scripts/packagelist.stretch.arm index 2a9c6eb..a8239d2a 100644 --- a/build/linux/sysroot_scripts/packagelist.stretch.arm +++ b/build/linux/sysroot_scripts/packagelist.stretch.arm
@@ -69,12 +69,20 @@ http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-3_1.15-1+deb9u1_armhf.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-dev_1.15-1+deb9u1_armhf.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5support0_1.15-1+deb9u1_armhf.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator1_0.4.92-4_armhf.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-1_0.4.92-4_armhf.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-dev_0.4.92-4_armhf.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator-dev_0.4.92-4_armhf.deb http://ftp.us.debian.org/debian/pool/main/liba/libasyncns/libasyncns0_0.8-6_armhf.deb http://ftp.us.debian.org/debian/pool/main/libb/libbsd/libbsd0_0.8.3-1_armhf.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap2_2.25-1_armhf.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap-dev_2.25-1_armhf.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap-ng/libcap-ng0_0.7.7-3+b1_armhf.deb http://ftp.us.debian.org/debian/pool/main/libd/libdatrie/libdatrie1_0.2.10-4+b1_armhf.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib4_12.10.2-2_armhf.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib-dev_12.10.2-2_armhf.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk3-4_12.10.2-2_armhf.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk4_12.10.2-2_armhf.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm2_2.4.74-1_armhf.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-amdgpu1_2.4.74-1_armhf.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-dev_2.4.74-1_armhf.deb @@ -95,6 +103,8 @@ http://ftp.us.debian.org/debian/pool/main/libi/libice/libice6_1.0.9-2_armhf.deb http://ftp.us.debian.org/debian/pool/main/libi/libidl/libidl-2-0_0.8.14-4_armhf.deb http://ftp.us.debian.org/debian/pool/main/libi/libidn/libidn11_1.33-1_armhf.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator3-7_0.5.0-3+b1_armhf.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator7_0.5.0-3+b1_armhf.deb http://ftp.us.debian.org/debian/pool/main/libj/libjpeg-turbo/libjpeg62-turbo_1.5.1-2_armhf.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp1_1.7.4-3_armhf.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp-dev_1.7.4-3_armhf.deb
diff --git a/build/linux/sysroot_scripts/packagelist.stretch.arm64 b/build/linux/sysroot_scripts/packagelist.stretch.arm64 index 51bd50b..3c13b8b 100644 --- a/build/linux/sysroot_scripts/packagelist.stretch.arm64 +++ b/build/linux/sysroot_scripts/packagelist.stretch.arm64
@@ -71,12 +71,20 @@ http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-3_1.15-1+deb9u1_arm64.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-dev_1.15-1+deb9u1_arm64.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5support0_1.15-1+deb9u1_arm64.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator1_0.4.92-4_arm64.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-1_0.4.92-4_arm64.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-dev_0.4.92-4_arm64.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator-dev_0.4.92-4_arm64.deb http://ftp.us.debian.org/debian/pool/main/liba/libasyncns/libasyncns0_0.8-6_arm64.deb http://ftp.us.debian.org/debian/pool/main/libb/libbsd/libbsd0_0.8.3-1_arm64.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap2_2.25-1_arm64.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap-dev_2.25-1_arm64.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap-ng/libcap-ng0_0.7.7-3+b1_arm64.deb http://ftp.us.debian.org/debian/pool/main/libd/libdatrie/libdatrie1_0.2.10-4+b1_arm64.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib4_12.10.2-2_arm64.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib-dev_12.10.2-2_arm64.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk3-4_12.10.2-2_arm64.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk4_12.10.2-2_arm64.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm2_2.4.74-1_arm64.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-amdgpu1_2.4.74-1_arm64.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-dev_2.4.74-1_arm64.deb @@ -95,6 +103,8 @@ http://ftp.us.debian.org/debian/pool/main/libi/libice/libice6_1.0.9-2_arm64.deb http://ftp.us.debian.org/debian/pool/main/libi/libidl/libidl-2-0_0.8.14-4_arm64.deb http://ftp.us.debian.org/debian/pool/main/libi/libidn/libidn11_1.33-1_arm64.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator3-7_0.5.0-3+b1_arm64.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator7_0.5.0-3+b1_arm64.deb http://ftp.us.debian.org/debian/pool/main/libj/libjpeg-turbo/libjpeg62-turbo_1.5.1-2_arm64.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp1_1.7.4-3_arm64.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp-dev_1.7.4-3_arm64.deb
diff --git a/build/linux/sysroot_scripts/packagelist.stretch.i386 b/build/linux/sysroot_scripts/packagelist.stretch.i386 index 95afc5a2..716f6b3 100644 --- a/build/linux/sysroot_scripts/packagelist.stretch.i386 +++ b/build/linux/sysroot_scripts/packagelist.stretch.i386
@@ -73,12 +73,20 @@ http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-3_1.15-1+deb9u1_i386.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-dev_1.15-1+deb9u1_i386.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5support0_1.15-1+deb9u1_i386.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator1_0.4.92-4_i386.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-1_0.4.92-4_i386.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-dev_0.4.92-4_i386.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator-dev_0.4.92-4_i386.deb http://ftp.us.debian.org/debian/pool/main/liba/libasyncns/libasyncns0_0.8-6_i386.deb http://ftp.us.debian.org/debian/pool/main/libb/libbsd/libbsd0_0.8.3-1_i386.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap2_2.25-1_i386.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap-dev_2.25-1_i386.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap-ng/libcap-ng0_0.7.7-3+b1_i386.deb http://ftp.us.debian.org/debian/pool/main/libd/libdatrie/libdatrie1_0.2.10-4+b1_i386.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib4_12.10.2-2_i386.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib-dev_12.10.2-2_i386.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk3-4_12.10.2-2_i386.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk4_12.10.2-2_i386.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm2_2.4.74-1_i386.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-amdgpu1_2.4.74-1_i386.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-dev_2.4.74-1_i386.deb @@ -96,6 +104,8 @@ http://ftp.us.debian.org/debian/pool/main/libi/libice/libice6_1.0.9-2_i386.deb http://ftp.us.debian.org/debian/pool/main/libi/libidl/libidl-2-0_0.8.14-4_i386.deb http://ftp.us.debian.org/debian/pool/main/libi/libidn/libidn11_1.33-1_i386.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator3-7_0.5.0-3+b1_i386.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator7_0.5.0-3+b1_i386.deb http://ftp.us.debian.org/debian/pool/main/libj/libjpeg-turbo/libjpeg62-turbo_1.5.1-2_i386.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp1_1.7.4-3_i386.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp-dev_1.7.4-3_i386.deb
diff --git a/build/linux/sysroot_scripts/packagelist.stretch.mips64el b/build/linux/sysroot_scripts/packagelist.stretch.mips64el index 594ac06..1a244bbd 100644 --- a/build/linux/sysroot_scripts/packagelist.stretch.mips64el +++ b/build/linux/sysroot_scripts/packagelist.stretch.mips64el
@@ -67,12 +67,20 @@ http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-3_1.15-1+deb9u1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-dev_1.15-1+deb9u1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5support0_1.15-1+deb9u1_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator1_0.4.92-4_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-1_0.4.92-4_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-dev_0.4.92-4_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator-dev_0.4.92-4_mips64el.deb http://ftp.us.debian.org/debian/pool/main/liba/libasyncns/libasyncns0_0.8-6_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libb/libbsd/libbsd0_0.8.3-1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap2_2.25-1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap-dev_2.25-1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap-ng/libcap-ng0_0.7.7-3+b1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libd/libdatrie/libdatrie1_0.2.10-4+b1_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib4_12.10.2-2_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib-dev_12.10.2-2_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk3-4_12.10.2-2_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk4_12.10.2-2_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm2_2.4.74-1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-amdgpu1_2.4.74-1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-dev_2.4.74-1_mips64el.deb @@ -89,6 +97,8 @@ http://ftp.us.debian.org/debian/pool/main/libi/libice/libice6_1.0.9-2_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libi/libidl/libidl-2-0_0.8.14-4_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libi/libidn/libidn11_1.33-1_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator3-7_0.5.0-3+b1_mips64el.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator7_0.5.0-3+b1_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libj/libjpeg-turbo/libjpeg62-turbo_1.5.1-2_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp1_1.7.4-3_mips64el.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp-dev_1.7.4-3_mips64el.deb
diff --git a/build/linux/sysroot_scripts/packagelist.stretch.mipsel b/build/linux/sysroot_scripts/packagelist.stretch.mipsel index a825f57b..159b412 100644 --- a/build/linux/sysroot_scripts/packagelist.stretch.mipsel +++ b/build/linux/sysroot_scripts/packagelist.stretch.mipsel
@@ -67,12 +67,20 @@ http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-3_1.15-1+deb9u1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5-dev_1.15-1+deb9u1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/k/krb5/libkrb5support0_1.15-1+deb9u1_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator1_0.4.92-4_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-1_0.4.92-4_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator3-dev_0.4.92-4_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/liba/libappindicator/libappindicator-dev_0.4.92-4_mipsel.deb http://ftp.us.debian.org/debian/pool/main/liba/libasyncns/libasyncns0_0.8-6_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libb/libbsd/libbsd0_0.8.3-1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap2_2.25-1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap2/libcap-dev_2.25-1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libc/libcap-ng/libcap-ng0_0.7.7-3+b1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libd/libdatrie/libdatrie1_0.2.10-4+b1_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib4_12.10.2-2_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-glib-dev_12.10.2-2_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk3-4_12.10.2-2_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/libd/libdbusmenu/libdbusmenu-gtk4_12.10.2-2_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm2_2.4.74-1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-amdgpu1_2.4.74-1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libd/libdrm/libdrm-dev_2.4.74-1_mipsel.deb @@ -89,6 +97,8 @@ http://ftp.us.debian.org/debian/pool/main/libi/libice/libice6_1.0.9-2_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libi/libidl/libidl-2-0_0.8.14-4_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libi/libidn/libidn11_1.33-1_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator3-7_0.5.0-3+b1_mipsel.deb +http://ftp.us.debian.org/debian/pool/main/libi/libindicator/libindicator7_0.5.0-3+b1_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libj/libjpeg-turbo/libjpeg62-turbo_1.5.1-2_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp1_1.7.4-3_mipsel.deb http://ftp.us.debian.org/debian/pool/main/libj/libjsoncpp/libjsoncpp-dev_1.7.4-3_mipsel.deb
diff --git a/build/linux/sysroot_scripts/sysroot-creator-stretch.sh b/build/linux/sysroot_scripts/sysroot-creator-stretch.sh index 077abd54..946734f 100755 --- a/build/linux/sysroot_scripts/sysroot-creator-stretch.sh +++ b/build/linux/sysroot_scripts/sysroot-creator-stretch.sh
@@ -32,6 +32,10 @@ DEBIAN_PACKAGES="\ comerr-dev krb5-multidev + libappindicator-dev + libappindicator1 + libappindicator3-1 + libappindicator3-dev libasound2 libasound2-dev libasyncns0 @@ -72,6 +76,10 @@ libdbus-1-3 libdbus-1-dev libdbus-glib-1-2 + libdbusmenu-glib-dev + libdbusmenu-glib4 + libdbusmenu-gtk3-4 + libdbusmenu-gtk4 libdrm-amdgpu1 libdrm-dev libdrm-nouveau2 @@ -133,6 +141,8 @@ libicu57 libidl-2-0 libidn11 + libindicator3-7 + libindicator7 libjbig0 libjpeg62-turbo libjson-glib-1.0-0
diff --git a/build/linux/sysroot_scripts/sysroots.json b/build/linux/sysroot_scripts/sysroots.json index 243394e..e0a566dc 100644 --- a/build/linux/sysroot_scripts/sysroots.json +++ b/build/linux/sysroot_scripts/sysroots.json
@@ -1,37 +1,37 @@ { "stretch_amd64": { - "Revision": "2202c161310ffde63729f29d27fe7bb24a0bc540", - "Sha1Sum": "eb7e2d2c563b6a6f6e32b967d5585a6d33636d35", + "Revision": "3c248ba4290a5ad07085b7af07e6785bf1ae5b66", + "Sha1Sum": "a668aafe335848c6e4aed11d0b32ea2d5c5a124d", "SysrootDir": "debian_stretch_amd64-sysroot", "Tarball": "debian_stretch_amd64_sysroot.tar.xz" }, "stretch_arm": { - "Revision": "2202c161310ffde63729f29d27fe7bb24a0bc540", - "Sha1Sum": "1d827c64de8f0205bef7ec0c9c7f769326e32141", + "Revision": "3c248ba4290a5ad07085b7af07e6785bf1ae5b66", + "Sha1Sum": "4658f558326d93d8a69fe6940bc19cf7de32cf4d", "SysrootDir": "debian_stretch_arm-sysroot", "Tarball": "debian_stretch_arm_sysroot.tar.xz" }, "stretch_arm64": { - "Revision": "1e9c6777efb621794e8385ab9b4faf3546c29bf2", - "Sha1Sum": "35fd438e9dfc39d75d1e03badc8b309e3ad94acd", + "Revision": "3c248ba4290a5ad07085b7af07e6785bf1ae5b66", + "Sha1Sum": "a3c530ff8a5d9be34dd6fc07a05188ea947116cf", "SysrootDir": "debian_stretch_arm64-sysroot", "Tarball": "debian_stretch_arm64_sysroot.tar.xz" }, "stretch_i386": { - "Revision": "2202c161310ffde63729f29d27fe7bb24a0bc540", - "Sha1Sum": "8fa3ac112fe5bb583624100379f715f3db5d6965", + "Revision": "3c248ba4290a5ad07085b7af07e6785bf1ae5b66", + "Sha1Sum": "98425d632814b45289ca6c3acb38d8e11c487ec6", "SysrootDir": "debian_stretch_i386-sysroot", "Tarball": "debian_stretch_i386_sysroot.tar.xz" }, "stretch_mips": { - "Revision": "2202c161310ffde63729f29d27fe7bb24a0bc540", - "Sha1Sum": "85a3f9e3f2d6ff2a5b2623f202689ef03ea12231", + "Revision": "3c248ba4290a5ad07085b7af07e6785bf1ae5b66", + "Sha1Sum": "dcb078646b49c94298cf702acc5ece28a689fea4", "SysrootDir": "debian_stretch_mips-sysroot", "Tarball": "debian_stretch_mips_sysroot.tar.xz" }, "stretch_mips64el": { - "Revision": "2202c161310ffde63729f29d27fe7bb24a0bc540", - "Sha1Sum": "004ad054e0613b9d8d51573068387625bb657d12", + "Revision": "3c248ba4290a5ad07085b7af07e6785bf1ae5b66", + "Sha1Sum": "a68c72c6b6d4fad8d43e268cc081ce6afeaa79e4", "SysrootDir": "debian_stretch_mips64el-sysroot", "Tarball": "debian_stretch_mips64el_sysroot.tar.xz" }
diff --git a/build/toolchain/BUILD.gn b/build/toolchain/BUILD.gn index dacbd0f..75701de 100644 --- a/build/toolchain/BUILD.gn +++ b/build/toolchain/BUILD.gn
@@ -3,9 +3,23 @@ # found in the LICENSE file. import("//build/toolchain/concurrent_links.gni") +import("//build/toolchain/goma.gni") + +declare_args() { + # Pool for non goma tasks. + action_pool_depth = -1 +} + +if (action_pool_depth == -1 || use_goma) { + action_pool_depth = exec_script("get_cpu_count.py", [], "value") +} if (current_toolchain == default_toolchain) { pool("link_pool") { depth = concurrent_links } + + pool("action_pool") { + depth = action_pool_depth + } }
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index c7248ba..89d5969 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -577,6 +577,10 @@ description = copy_description } + tool("action") { + pool = "//build/toolchain:action_pool($default_toolchain)" + } + forward_variables_from(invoker, [ "deps" ]) } }
diff --git a/build/toolchain/get_cpu_count.py b/build/toolchain/get_cpu_count.py new file mode 100644 index 0000000..1609ce6 --- /dev/null +++ b/build/toolchain/get_cpu_count.py
@@ -0,0 +1,21 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This script shows cpu count to specify capacity of action pool. + +import multiprocessing +import sys + +def main(): + try: + cpu_count = multiprocessing.cpu_count() + except: + cpu_count = 1 + + print cpu_count + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn index f66bca0..7fa01dc 100644 --- a/build/toolchain/mac/BUILD.gn +++ b/build/toolchain/mac/BUILD.gn
@@ -436,6 +436,10 @@ description = "COMPILE_XCASSETS {{output}}" pool = ":bundle_pool($default_toolchain)" } + + tool("action") { + pool = "//build/toolchain:action_pool($default_toolchain)" + } } }
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index df1a50fc..4de6381 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -339,10 +339,16 @@ tool("stamp") { command = stamp_command description = stamp_description + pool = "//build/toolchain:action_pool($default_toolchain)" } tool("copy") { command = copy_command description = copy_description + pool = "//build/toolchain:action_pool($default_toolchain)" + } + + tool("action") { + pool = "//build/toolchain:action_pool($default_toolchain)" } } }
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc index 4e4aaf5..3dc8fad 100644 --- a/cc/paint/paint_op_writer.cc +++ b/cc/paint/paint_op_writer.cc
@@ -150,8 +150,7 @@ void PaintOpWriter::Write(const DrawImage& image) { if (enable_security_constraints_) { SkBitmap bm; - if (!image.paint_image().GetSkImage()->asLegacyBitmap( - &bm, SkImage::LegacyBitmapMode::kRO_LegacyBitmapMode)) { + if (!image.paint_image().GetSkImage()->asLegacyBitmap(&bm)) { Write(static_cast<uint8_t>(PaintOp::SerializedImageType::kNoImage)); return; }
diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc index 10c0428d..505d92e0 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.cc +++ b/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -49,6 +49,8 @@ } base::UnguessableToken SharedMemoryGuid() override { + if (!gpu_memory_buffer) + return {}; return gpu_memory_buffer->GetHandle().handle.GetGUID(); }
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc index 4a83bf0..f114850 100644 --- a/cc/resources/resource_pool.cc +++ b/cc/resources/resource_pool.cc
@@ -649,11 +649,29 @@ const LayerTreeResourceProvider* resource_provider, bool dump_parent, bool is_free) const { + base::UnguessableToken shm_guid; + base::trace_event::MemoryAllocatorDumpGuid backing_guid; if (!dump_parent) { + if (shared_bitmap_) { + // Software resources are in shared memory but are kept closed to avoid + // holding an fd open. So there is no SharedMemoryHandle to get a guid + // from. + DCHECK(!shared_bitmap_->GetSharedMemoryHandle().IsValid()); + backing_guid = viz::GetSharedBitmapGUIDForTracing(shared_bitmap_->id()); + } else if (gpu_backing_) { + shm_guid = gpu_backing_->SharedMemoryGuid(); + if (shm_guid.is_empty()) { + auto* dump_manager = + base::trace_event::MemoryDumpManager::GetInstance(); + backing_guid = + gpu_backing_->MemoryDumpGuid(dump_manager->GetTracingProcessId()); + } + } + // If |dump_parent| is false, the ownership of the resource is in the // ResourcePool, so we can see if any memory is allocated. If not, then // don't dump it. - if (!shared_bitmap_ && !gpu_backing_) + if (shm_guid.is_empty() && backing_guid.empty()) return; } @@ -677,32 +695,12 @@ // the root ownership. The gpu processes uses 0, so 2 is sufficient, and was // chosen historically and there is no need to adjust it. const int kImportance = 2; - if (shared_bitmap_) { - // Software resources are in shared memory but are kept closed to avoid - // holding an fd open. So there is no SharedMemoryHandle to get a guid - // from. - DCHECK(!shared_bitmap_->GetSharedMemoryHandle().IsValid()); - base::trace_event::MemoryAllocatorDumpGuid guid = - viz::GetSharedBitmapGUIDForTracing(shared_bitmap_->id()); - DCHECK(!guid.empty()); - pmd->CreateSharedGlobalAllocatorDump(guid); - pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); + if (!shm_guid.is_empty()) { + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shm_guid, kImportance); } else { - // Gpu compositing resources can be shared memory-backed (e.g. - // GpuMemoryBuffers can be backed by it). - const base::UnguessableToken& shm_guid = gpu_backing_->SharedMemoryGuid(); - if (!shm_guid.is_empty()) { - pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shm_guid, - kImportance); - } else { - auto* dump_manager = - base::trace_event::MemoryDumpManager::GetInstance(); - auto backing_guid = - gpu_backing_->MemoryDumpGuid(dump_manager->GetTracingProcessId()); - DCHECK(!backing_guid.empty()); - pmd->CreateSharedGlobalAllocatorDump(backing_guid); - pmd->AddOwnershipEdge(dump->guid(), backing_guid, kImportance); - } + DCHECK(!backing_guid.empty()); + pmd->CreateSharedGlobalAllocatorDump(backing_guid); + pmd->AddOwnershipEdge(dump->guid(), backing_guid, kImportance); } }
diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h index 3a165c1..03c5271 100644 --- a/cc/resources/resource_pool.h +++ b/cc/resources/resource_pool.h
@@ -55,7 +55,8 @@ uint32_t texture_target; gpu::SyncToken returned_sync_token; - // Guids for for memory dumps. This guid will always be valid. + // Guids for for memory dumps. This guid will be valid once the GpuBacking + // has memory allocated. virtual base::trace_event::MemoryAllocatorDumpGuid MemoryDumpGuid( uint64_t tracing_process_id) = 0; // Some gpu resources can be shared memory-backed, and this guid should be
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index adef923..315dc70 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -449,7 +449,6 @@ "//ui/android:ui_java", "//url/mojom:url_mojom_gurl_java", ] - srcjar_deps = [ "//base:base_build_config_gen" ] package_name = manifest_package }
diff --git a/chrome/android/java/res/layout/passwords_error_dialog.xml b/chrome/android/java/res/layout/passwords_error_dialog.xml new file mode 100644 index 0000000..62b511e --- /dev/null +++ b/chrome/android/java/res/layout/passwords_error_dialog.xml
@@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2018 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. --> + +<!-- Used by ExportErrorDialogFragment of passwords preferences. --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + style="@style/AlertDialogContent"> + + <TextView + android:id="@+id/passwords_error_main_description" + android:layout_height="wrap_content" + android:layout_width="match_parent"/> + + <TextView + android:id="@+id/passwords_error_detailed_description" + android:layout_marginTop="14dp" + android:layout_height="wrap_content" + android:layout_width="match_parent"/> + +</LinearLayout>
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 d1ec012a..e9a561c 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
@@ -960,8 +960,9 @@ getToolbarManager().addCustomActionButton( params.getIcon(getResources()), params.getDescription(), v -> { if (getActivityTab() == null) return; - mIntentDataProvider.sendButtonPendingIntentWithUrl( - getApplicationContext(), params, getActivityTab().getUrl()); + mIntentDataProvider.sendButtonPendingIntentWithUrlAndTitle( + getApplicationContext(), params, getActivityTab().getUrl(), + getActivityTab().getTitle()); RecordUserAction.record("CustomTabsCustomActionButtonClick"); if (mIntentDataProvider.shouldEnableEmbeddedMediaExperience() && TextUtils.equals( @@ -988,8 +989,8 @@ public boolean onOptionsItemSelected(MenuItem item) { int menuIndex = getAppMenuPropertiesDelegate().getIndexOfMenuItem(item); if (menuIndex >= 0) { - mIntentDataProvider.clickMenuItemWithUrl(this, menuIndex, - getTabModelSelector().getCurrentTab().getUrl()); + mIntentDataProvider.clickMenuItemWithUrlAndTitle( + this, menuIndex, getActivityTab().getUrl(), getActivityTab().getTitle()); RecordUserAction.record("CustomTabsMenuCustomMenuItem"); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index 3023b49..7c5c55e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -439,22 +439,27 @@ /** * Triggers the client-defined action when the user clicks a custom menu item. + * @param activity The {@link ChromeActivity} to use for sending the {@link PendingIntent}. * @param menuIndex The index that the menu item is shown in the result of - * {@link #getMenuTitles()} + * {@link #getMenuTitles()}. + * @param url The URL to attach as additional data to the {@link PendingIntent}. + * @param title The title to attach as additional data to the {@link PendingIntent}. */ - public void clickMenuItemWithUrl(ChromeActivity activity, int menuIndex, String url) { + public void clickMenuItemWithUrlAndTitle( + ChromeActivity activity, int menuIndex, String url, String title) { Intent addedIntent = new Intent(); addedIntent.setData(Uri.parse(url)); + addedIntent.putExtra(Intent.EXTRA_SUBJECT, title); try { // Media viewers pass in PendingIntents that contain CHOOSER Intents. Setting the data // in these cases prevents the Intent from firing correctly. - String title = mMenuEntries.get(menuIndex).first; + String menuTitle = mMenuEntries.get(menuIndex).first; PendingIntent pendingIntent = mMenuEntries.get(menuIndex).second; pendingIntent.send( activity, 0, isMediaViewer() ? null : addedIntent, mOnFinished, null); if (shouldEnableEmbeddedMediaExperience() - && TextUtils.equals( - title, activity.getString(R.string.download_manager_open_with))) { + && TextUtils.equals(menuTitle, + activity.getString(R.string.download_manager_open_with))) { RecordUserAction.record("CustomTabsMenuCustomMenuItem.DownloadsUI.OpenWith"); } } catch (CanceledException e) { @@ -468,11 +473,13 @@ * @param context The context to use for sending the {@link PendingIntent}. * @param params The parameters for the custom button. * @param url The URL to attach as additional data to the {@link PendingIntent}. + * @param title The title to attach as additional data to the {@link PendingIntent}. */ - public void sendButtonPendingIntentWithUrl( - Context context, CustomButtonParams params, String url) { + public void sendButtonPendingIntentWithUrlAndTitle( + Context context, CustomButtonParams params, String url, String title) { Intent addedIntent = new Intent(); addedIntent.setData(Uri.parse(url)); + addedIntent.putExtra(Intent.EXTRA_SUBJECT, title); try { params.getPendingIntent().send(context, 0, addedIntent, mOnFinished, null); } catch (CanceledException e) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java index def8397..3e0106f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java
@@ -410,7 +410,14 @@ * @param info The resolve info. */ public boolean isInstantAppResolveInfo(ResolveInfo info) { - if (info == null || info.activityInfo == null) return false; - return EPHEMERAL_INSTALLER_CLASS.equals(info.activityInfo.name); + if (info == null) return false; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return info.isInstantAppAvailable; + } else if (info.activityInfo != null) { + return EPHEMERAL_INSTALLER_CLASS.equals(info.activityInfo.name); + } + + return false; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerWrapper.java new file mode 100644 index 0000000..a44e198 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerWrapper.java
@@ -0,0 +1,152 @@ +// Copyright 2018 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.media.remote; + +import com.google.android.gms.cast.CastDevice; +import com.google.android.gms.cast.MediaInfo; +import com.google.android.gms.cast.MediaStatus; +import com.google.android.gms.cast.RemoteMediaPlayer; +import com.google.android.gms.common.api.GoogleApiClient; + +import org.chromium.chrome.browser.media.router.cast.CastSessionUtil; +import org.chromium.chrome.browser.media.ui.MediaNotificationInfo; +import org.chromium.chrome.browser.media.ui.MediaNotificationManager; + +/** + * A wrapper around a RemoteMediaPlayer that exposes simple playback commands without the + * the complexities of the GMS cast calls. + */ +public class RemoteMediaPlayerWrapper implements RemoteMediaPlayer.OnMetadataUpdatedListener, + RemoteMediaPlayer.OnStatusUpdatedListener { + private final CastDevice mCastDevice; + + private GoogleApiClient mApiClient; + private RemoteMediaPlayer mMediaPlayer; + private MediaNotificationInfo.Builder mNotificationBuilder; + + public RemoteMediaPlayerWrapper(GoogleApiClient apiClient, + MediaNotificationInfo.Builder notificationBuilder, CastDevice castDevice) { + mApiClient = apiClient; + mCastDevice = castDevice; + mNotificationBuilder = notificationBuilder; + + mMediaPlayer = new RemoteMediaPlayer(); + mMediaPlayer.setOnStatusUpdatedListener(this); + mMediaPlayer.setOnMetadataUpdatedListener(this); + + updateNotificationMetadata(); + } + + private void updateNotificationMetadata() { + CastSessionUtil.setNotificationMetadata(mNotificationBuilder, mCastDevice, mMediaPlayer); + MediaNotificationManager.show(mNotificationBuilder.build()); + } + + private boolean canSendCommand() { + return mApiClient != null && mMediaPlayer != null && mApiClient.isConnected(); + } + + // RemoteMediaPlayer.OnStatusUpdatedListener implementation. + @Override + public void onStatusUpdated() { + MediaStatus mediaStatus = mMediaPlayer.getMediaStatus(); + if (mediaStatus == null) return; + + int playerState = mediaStatus.getPlayerState(); + if (playerState == MediaStatus.PLAYER_STATE_PAUSED + || playerState == MediaStatus.PLAYER_STATE_PLAYING) { + mNotificationBuilder.setPaused(playerState != MediaStatus.PLAYER_STATE_PLAYING); + mNotificationBuilder.setActions( + MediaNotificationInfo.ACTION_STOP | MediaNotificationInfo.ACTION_PLAY_PAUSE); + } else { + mNotificationBuilder.setActions(MediaNotificationInfo.ACTION_STOP); + } + MediaNotificationManager.show(mNotificationBuilder.build()); + } + + // RemoteMediaPlayer.OnMetadataUpdatedListener implementation. + @Override + public void onMetadataUpdated() { + updateNotificationMetadata(); + } + + /** + * Forwards the message to the underlying RemoteMediaPlayer. + */ + public void onMediaMessage(String message) { + if (mMediaPlayer != null) + mMediaPlayer.onMessageReceived(mCastDevice, CastSessionUtil.MEDIA_NAMESPACE, message); + } + + /** + * Starts loading the provided media URL, without autoplay. + */ + public void load(String mediaUrl) { + if (!canSendCommand()) return; + + MediaInfo.Builder mediaInfoBuilder = + new MediaInfo.Builder(mediaUrl).setContentType("*/*").setStreamType( + MediaInfo.STREAM_TYPE_BUFFERED); + + mMediaPlayer.load(mApiClient, mediaInfoBuilder.build(), /* autoplay */ false); + } + + /** + * Starts playback. No-op if are not in a valid state. + * Doesn't verify the command's success/failure. + */ + public void play() { + if (!canSendCommand()) return; + + mMediaPlayer.play(mApiClient); + } + + /** + * Pauses playback. No-op if are not in a valid state. + * Doesn't verify the command's success/failure. + */ + public void pause() { + if (!canSendCommand()) return; + + mMediaPlayer.pause(mApiClient); + } + + /** + * Sets the mute state. Does not affect the stream volume. + * No-op if are not in a valid state. Doesn't verify the command's success/failure. + */ + public void setMute(boolean mute) { + if (!canSendCommand()) return; + + mMediaPlayer.setStreamMute(mApiClient, mute); + } + + /** + * Sets the stream volume. Does not affect the mute state. + * No-op if are not in a valid state. Doesn't verify the command's success/failure. + */ + public void setVolume(double volume) { + if (!canSendCommand()) return; + + mMediaPlayer.setStreamVolume(mApiClient, volume); + } + + /** + * Seeks to the given position (in milliseconds). + * No-op if are not in a valid state. Doesn't verify the command's success/failure. + */ + public void seek(long position) { + if (!canSendCommand()) return; + + mMediaPlayer.seek(mApiClient, position); + } + + /** + * Called when the session has stopped, and we should no longer send commands. + */ + public void clearApiClient() { + mApiClient = null; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingCastSession.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingCastSession.java index 2d8d647..f20f127b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingCastSession.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingCastSession.java
@@ -7,8 +7,6 @@ import com.google.android.gms.cast.ApplicationMetadata; import com.google.android.gms.cast.Cast; import com.google.android.gms.cast.CastDevice; -import com.google.android.gms.cast.MediaStatus; -import com.google.android.gms.cast.RemoteMediaPlayer; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.common.api.Status; @@ -17,10 +15,10 @@ import org.json.JSONObject; import org.chromium.chrome.R; +import org.chromium.chrome.browser.media.remote.RemoteMediaPlayerWrapper; import org.chromium.chrome.browser.media.router.cast.CastMessageHandler; import org.chromium.chrome.browser.media.router.cast.CastSession; import org.chromium.chrome.browser.media.router.cast.CastSessionInfo; -import org.chromium.chrome.browser.media.router.cast.CastSessionUtil; import org.chromium.chrome.browser.media.router.cast.ChromeCastSessionManager; import org.chromium.chrome.browser.media.router.cast.MediaSource; import org.chromium.chrome.browser.media.ui.MediaNotificationInfo; @@ -42,7 +40,7 @@ private String mApplicationStatus; private ApplicationMetadata mApplicationMetadata; private MediaNotificationInfo.Builder mNotificationBuilder; - private RemoteMediaPlayer mMediaPlayer; + private RemoteMediaPlayerWrapper mMediaPlayerWrapper; private boolean mStoppingApplication = false; public RemotingCastSession(GoogleApiClient apiClient, String sessionId, @@ -54,35 +52,6 @@ mApplicationMetadata = metadata; mSessionId = sessionId; - mMediaPlayer = new RemoteMediaPlayer(); - mMediaPlayer.setOnStatusUpdatedListener(new RemoteMediaPlayer.OnStatusUpdatedListener() { - @Override - public void onStatusUpdated() { - MediaStatus mediaStatus = mMediaPlayer.getMediaStatus(); - if (mediaStatus == null) return; - - int playerState = mediaStatus.getPlayerState(); - if (playerState == MediaStatus.PLAYER_STATE_PAUSED - || playerState == MediaStatus.PLAYER_STATE_PLAYING) { - mNotificationBuilder.setPaused(playerState != MediaStatus.PLAYER_STATE_PLAYING); - mNotificationBuilder.setActions(MediaNotificationInfo.ACTION_STOP - | MediaNotificationInfo.ACTION_PLAY_PAUSE); - } else { - mNotificationBuilder.setActions(MediaNotificationInfo.ACTION_STOP); - } - MediaNotificationManager.show(mNotificationBuilder.build()); - } - }); - mMediaPlayer.setOnMetadataUpdatedListener( - new RemoteMediaPlayer.OnMetadataUpdatedListener() { - @Override - public void onMetadataUpdated() { - CastSessionUtil.setNotificationMetadata( - mNotificationBuilder, mCastDevice, mMediaPlayer); - MediaNotificationManager.show(mNotificationBuilder.build()); - } - }); - mNotificationBuilder = new MediaNotificationInfo.Builder() .setPaused(false) @@ -97,8 +66,11 @@ .setDefaultNotificationLargeIcon(R.drawable.cast_playing_square) .setId(R.id.presentation_notification) .setListener(this); - CastSessionUtil.setNotificationMetadata(mNotificationBuilder, mCastDevice, mMediaPlayer); - MediaNotificationManager.show(mNotificationBuilder.build()); + + mMediaPlayerWrapper = + new RemoteMediaPlayerWrapper(mApiClient, mNotificationBuilder, mCastDevice); + + mMediaPlayerWrapper.load(((RemotingMediaSource) source).getMediaUrl()); } @Override @@ -166,6 +138,7 @@ mSessionId = null; mApiClient = null; + mMediaPlayerWrapper.clearApiClient(); ChromeCastSessionManager.get().onSessionEnded(); mStoppingApplication = false; @@ -180,8 +153,7 @@ @Override public void onMediaMessage(String message) { - if (mMediaPlayer != null) - mMediaPlayer.onMessageReceived(mCastDevice, CastSessionUtil.MEDIA_NAMESPACE, message); + mMediaPlayerWrapper.onMediaMessage(message); } @Override @@ -195,16 +167,12 @@ @Override public void onPlay(int actionSource) { - if (mMediaPlayer == null || isApiClientInvalid()) return; - - mMediaPlayer.play(mApiClient); + mMediaPlayerWrapper.play(); } @Override public void onPause(int actionSource) { - if (mMediaPlayer == null || isApiClientInvalid()) return; - - mMediaPlayer.pause(mApiClient); + mMediaPlayerWrapper.pause(); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportErrorDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportErrorDialogFragment.java new file mode 100644 index 0000000..fa584a1 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportErrorDialogFragment.java
@@ -0,0 +1,101 @@ +// Copyright 2018 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.preferences.password; + +import android.app.Dialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.view.View; +import android.widget.TextView; + +import org.chromium.chrome.R; + +/** + * Shows the dialog that explains to the user the error which just happened during exporting and + * optionally helps them to take actions to fix that (learning more, retrying export). + */ +public class ExportErrorDialogFragment extends DialogFragment { + /** Parameters to fill in the strings in the dialog. Pass them through {@link #initialize()}.*/ + public static class ErrorDialogParams { + /** The string resource ID for the label of the positive button. Required. */ + public int positiveButtonLabelId; + + /** The main description of the error. Required. */ + public String description; + + /** + * An optional detailed description. Will be prefixed with "Details:" and displayed below + * the main one.*/ + @Nullable + public String detailedDescription; + } + + // This handler is used to answer the user actions on the dialog. + private DialogInterface.OnClickListener mHandler; + + /** Defines the strings to be shown. Set in {@link #initialize()}. */ + private ErrorDialogParams mParams; + + /** + * Sets the click handler for the dialog buttons. + * @param mHandler The handler to use. + */ + public void setExportErrorHandler(DialogInterface.OnClickListener handler) { + mHandler = handler; + } + + /** + * Opens the dialog with the warning and sets the button listener to a fragment identified by ID + * passed in arguments. + */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + assert mParams != null; + final View dialog = + getActivity().getLayoutInflater().inflate(R.layout.passwords_error_dialog, null); + final TextView mainDescription = + (TextView) dialog.findViewById(R.id.passwords_error_main_description); + mainDescription.setText(mParams.description); + final TextView detailedDescription = + (TextView) dialog.findViewById(R.id.passwords_error_detailed_description); + if (mParams.detailedDescription != null) { + detailedDescription.setText(mParams.detailedDescription); + } else { + detailedDescription.setVisibility(View.GONE); + } + return new AlertDialog.Builder(getActivity(), R.style.SimpleDialog) + .setView(dialog) + .setTitle(R.string.save_password_preferences_export_error_title) + .setPositiveButton(mParams.positiveButtonLabelId, mHandler) + .setNegativeButton(R.string.close, mHandler) + .create(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // If there is savedInstanceState, then the dialog is being recreated by Android and will + // lack the necessary callbacks. The user likely already saw it first and then replaced the + // current activity. Therefore just close the dialog. + if (savedInstanceState != null) { + dismiss(); + return; + } + } + + /** + * Set the parameters for the strings to be shown. Must be called exactly once, before the + * dialog is shown. + */ + public void initialize(ErrorDialogParams params) { + assert mParams == null && params != null; + assert params.positiveButtonLabelId != 0; + assert params.description != null; + mParams = params; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java index 52090b2..885a1e22 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java
@@ -16,10 +16,19 @@ * Shows the dialog that gives the user some tips for how to treat the exported passwords securely. */ public class ExportWarningDialogFragment extends DialogFragment { - // This handler is used to answer the user actions on the dialog. - private DialogInterface.OnClickListener mHandler; + /** + * This interface combines handling the clicks on the buttons and the general dismissal of the + * dialog. + */ + public interface Handler extends DialogInterface.OnClickListener { + /** Handle the dismissal of the dialog.*/ + void onDismiss(); + } - public void setExportWarningHandler(DialogInterface.OnClickListener handler) { + // This handler is used to answer the user actions on the dialog. + private Handler mHandler; + + public void setExportWarningHandler(Handler handler) { mHandler = handler; } @@ -48,4 +57,9 @@ return; } } + + @Override + public void onDismiss(DialogInterface dialog) { + mHandler.onDismiss(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java index 7db074b..ef87092 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
@@ -162,6 +162,14 @@ @Nullable private ProgressBarDialogFragment mProgressBarDialogFragment; + // If an error dialog should be shown, this contains the arguments for it, such as the error + // message. If no error dialog should be shown, this is null. + @Nullable + private ExportErrorDialogFragment.ErrorDialogParams mErrorDialogParams; + + // True as long as the export warning dialog is showing. + private boolean mExportWarningShowing; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -311,7 +319,8 @@ if (mExportState == EXPORT_STATE_INACTIVE) return; if (result.mError != null) { - showExportErrorAndAbort(result.mError); + showExportErrorAndAbort(R.string.save_password_preferences_export_tips, + result.mError, R.string.try_again); } else { mExportFileUri = result.mUri; tryExporting(); @@ -321,64 +330,104 @@ task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, serializedPasswords); } + /** Starts the password export flow. + * Current state of export flow: the user just tapped the menu item for export + * The next steps are: passing reauthentication, confirming the export, waiting for exported + * data (if needed) and choosing a consumer app for the data. + */ + private void startExporting() { + assert mExportState == EXPORT_STATE_INACTIVE; + // Disable re-triggering exporting until the current exporting finishes. + mExportState = EXPORT_STATE_REQUESTED; + + // Start fetching the serialized passwords now to use the time the user spends + // reauthenticating and reading the warning message. If the user cancels the export or + // fails the reauthentication, the serialised passwords will simply get ignored when + // they arrive. + PasswordManagerHandlerProvider.getInstance().getPasswordManagerHandler().serializePasswords( + new Callback<String>() { + @Override + public void onResult(String serializedPasswords) { + shareSerializedPasswords(serializedPasswords); + } + }); + if (!ReauthenticationManager.isScreenLockSetUp(getActivity().getApplicationContext())) { + Toast.makeText(getActivity().getApplicationContext(), + R.string.password_export_set_lock_screen, Toast.LENGTH_LONG) + .show(); + // Re-enable exporting, the current one was cancelled by Chrome. + mExportState = EXPORT_STATE_INACTIVE; + } else if (ReauthenticationManager.authenticationStillValid( + ReauthenticationManager.REAUTH_SCOPE_BULK)) { + exportAfterReauth(); + } else { + ReauthenticationManager.displayReauthenticationFragment( + R.string.lockscreen_description_export, getView().getId(), getFragmentManager(), + ReauthenticationManager.REAUTH_SCOPE_BULK); + } + } + @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.export_passwords) { - assert mExportState == EXPORT_STATE_INACTIVE; - // Disable re-triggering exporting until the current exporting finishes. - mExportState = EXPORT_STATE_REQUESTED; - - // Start fetching the serialized passwords now to use the time the user spends - // reauthenticating and reading the warning message. If the user cancels the export or - // fails the reauthentication, the serialised passwords will simply get ignored when - // they arrive. - PasswordManagerHandlerProvider.getInstance() - .getPasswordManagerHandler() - .serializePasswords(new Callback<String>() { - @Override - public void onResult(String serializedPasswords) { - shareSerializedPasswords(serializedPasswords); - } - }); - if (!ReauthenticationManager.isScreenLockSetUp(getActivity().getApplicationContext())) { - Toast.makeText(getActivity().getApplicationContext(), - R.string.password_export_set_lock_screen, Toast.LENGTH_LONG) - .show(); - // Re-enable exporting, the current one was cancelled by Chrome. - mExportState = EXPORT_STATE_INACTIVE; - } else if (ReauthenticationManager.authenticationStillValid( - ReauthenticationManager.REAUTH_SCOPE_BULK)) { - exportAfterReauth(); - } else { - ReauthenticationManager.displayReauthenticationFragment( - R.string.lockscreen_description_export, getView().getId(), - getFragmentManager(), ReauthenticationManager.REAUTH_SCOPE_BULK); - } + startExporting(); return true; } return super.onOptionsItemSelected(item); } - /** Continues with the password export flow after the user successfully reauthenticated. */ + /** + * Continues with the password export flow after the user successfully reauthenticated. + * Current state of export flow: the user tapped the menu item for export and passed + * reauthentication. The next steps are: confirming the export, waiting for exported data (if + * needed) and choosing a consumer app for the data. + */ private void exportAfterReauth() { + assert !mExportWarningShowing; ExportWarningDialogFragment exportWarningDialogFragment = new ExportWarningDialogFragment(); - exportWarningDialogFragment.setExportWarningHandler(new DialogInterface.OnClickListener() { - /** On positive button response asks the parent to continue with the export flow. */ - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == AlertDialog.BUTTON_POSITIVE) { - mExportState = EXPORT_STATE_CONFIRMED; - tryExporting(); - } - } - }); + exportWarningDialogFragment.setExportWarningHandler( + new ExportWarningDialogFragment.Handler() { + /** + * On positive button response asks the parent to continue with the export flow. + */ + @Override + public void onClick(DialogInterface dialog, int which) { + if (which == AlertDialog.BUTTON_POSITIVE) { + mExportState = EXPORT_STATE_CONFIRMED; + // If the error dialog has been waiting, display it now, otherwise + // continue the export flow. + if (mErrorDialogParams != null) { + showExportErrorDialogFragment(); + } else { + tryExporting(); + } + } + } + + /** + * Mark the dismissal of the dialog, so that waiting UI (such as error + * reporting) can be shown. + */ + @Override + public void onDismiss() { + mExportWarningShowing = false; + // If the error dialog has been waiting, display it now. + if (mErrorDialogParams != null) showExportErrorDialogFragment(); + } + }); + mExportWarningShowing = true; exportWarningDialogFragment.show(getFragmentManager(), null); } /** * Starts the exporting intent if both blocking events are completed: serializing and the * confirmation flow. + * At this point, the user the user has tapped the menu item for export and passed + * reauthentication. Upon calling this method, the user has either also confirmed the export, or + * the exported data have been prepared. The method is called twice, once for each of those + * events. The next step after both the export is confirmed and the data is ready is to offer + * the user an intent chooser for sharing the exported passwords. */ private void tryExporting() { if (mExportState != EXPORT_STATE_CONFIRMED) return; @@ -407,14 +456,61 @@ /** * Call this to abort the export UI flow and display an error description to the user. - * @param description A string with a brief explanation of the error. + * @param descriptionId The resource ID of a string with a brief explanation of the error. + * @param detailedDescription An optional string with more technical details about the error. + * @param positiveButtonLabelId The resource ID of the label of the positive button in the error + * dialog. */ - private void showExportErrorAndAbort(String description) { - // TODO(crbug.com/788701): Implement. Ensure that if ExportWarningDialogFragment is shown, - // then Chrome waits until the user closes it to avoid changing UI under their fingers. + @VisibleForTesting + public void showExportErrorAndAbort( + int descriptionId, @Nullable String detailedDescription, int positiveButtonLabelId) { + assert mErrorDialogParams == null; if (mProgressBarDialogFragment != null) mProgressBarDialogFragment.dismiss(); - // Re-enable exporting, the current one was just cancelled. - mExportState = EXPORT_STATE_INACTIVE; + + mErrorDialogParams = new ExportErrorDialogFragment.ErrorDialogParams(); + mErrorDialogParams.positiveButtonLabelId = positiveButtonLabelId; + mErrorDialogParams.description = getActivity().getResources().getString(descriptionId); + if (detailedDescription != null) { + mErrorDialogParams.detailedDescription = getActivity().getResources().getString( + R.string.save_password_preferences_export_error_details, detailedDescription); + } + + if (!mExportWarningShowing) showExportErrorDialogFragment(); + } + + /** + * This is a helper method to {@link showExportErrorAndAbort}, responsible for showing the + * actual UI.*/ + private void showExportErrorDialogFragment() { + assert mErrorDialogParams != null; + + ExportErrorDialogFragment exportErrorDialogFragment = new ExportErrorDialogFragment(); + int positiveButtonLabelId = mErrorDialogParams.positiveButtonLabelId; + exportErrorDialogFragment.initialize(mErrorDialogParams); + mErrorDialogParams = null; + + exportErrorDialogFragment.setExportErrorHandler(new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (which == AlertDialog.BUTTON_POSITIVE) { + if (positiveButtonLabelId + == R.string.save_password_preferences_export_learn_google_drive) { + // Link to the help article about how to use Google Drive. + Intent intent = new Intent(Intent.ACTION_VIEW, + Uri.parse("https://support.google.com/drive/answer/2424384")); + intent.setPackage(getActivity().getPackageName()); + getActivity().startActivity(intent); + } else if (positiveButtonLabelId == R.string.try_again) { + mExportState = EXPORT_STATE_INACTIVE; + startExporting(); + } + } else if (which == AlertDialog.BUTTON_NEGATIVE) { + // Re-enable exporting, the current one was just cancelled. + mExportState = EXPORT_STATE_INACTIVE; + } + } + }); + exportErrorDialogFragment.show(getFragmentManager(), null); } /** @@ -434,8 +530,6 @@ try { tempFile = File.createTempFile("pwd-export", ".csv", passwordsDir); } catch (IOException e) { - // TODO(crbug.com/788701): Change e.getMessage to an appropriate error, following the - // mocks. return new ExportResult(e.getMessage()); } tempFile.deleteOnExit(); @@ -443,15 +537,11 @@ new FileOutputStream(tempFile), Charset.forName("UTF-8")))) { tempWriter.write(serializedPasswords); } catch (IOException e) { - // TODO(crbug.com/788701): Change e.getMessage to an appropriate error, following the - // mocks. return new ExportResult(e.getMessage()); } try { return new ExportResult(ContentUriUtils.getContentUriFromFile(tempFile)); } catch (IllegalArgumentException e) { - // TODO(crbug.com/788701): Display an error, because the result of Uri.fromFile is not - // going to be shareable. return new ExportResult(e.getMessage()); } } @@ -475,8 +565,8 @@ chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ContextUtils.getApplicationContext().startActivity(chooser); } catch (ActivityNotFoundException e) { - // TODO(crbug.com/788701): If no app handles it, display the appropriate error. - showExportErrorAndAbort(e.getMessage()); + showExportErrorAndAbort(R.string.save_password_preferences_export_no_app, null, + R.string.save_password_preferences_export_learn_google_drive); } mExportFileUri = null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java index df9626f1..8fb1627 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -1080,10 +1080,12 @@ mLocationBarNtpOffsetLeft = 0; mLocationBarNtpOffsetRight = 0; + boolean isNtp = false; Tab currentTab = getToolbarDataProvider().getTab(); if (currentTab != null) { NewTabPage ntp = getToolbarDataProvider().getNewTabPageForCurrentTab(); if (ntp != null) { + isNtp = true; ntp.setUrlFocusChangeAnimationPercent(mUrlFocusChangePercent); } @@ -1112,7 +1114,9 @@ isLocationBarRtl, locationBarBaseTranslationX)); mLocationBar.setUrlFocusChangePercent(mUrlExpansionPercent); - if (mLocationBar.useModernDesign()) { + // Only transition theme colors if in static tab mode that is not the NTP. In practice this + // only runs when you focus the omnibox on a web page. + if (mLocationBar.useModernDesign() && !isNtp && mTabSwitcherState == STATIC_TAB) { int defaultColor = ColorUtils.getDefaultThemeColor(getResources(), true, isIncognito()); int defaultLocationBarColor = getLocationBarColorForToolbarColor(defaultColor); int primaryColor = getToolbarDataProvider().getPrimaryColor();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java index 0768dff6..856ae9a5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApi.java
@@ -71,6 +71,13 @@ boolean bootsToVr(); /** + * Adds the necessary VR flags to an intent. + * @param intent The intent to add VR flags to. + * @return the intent with VR flags set. + */ + Intent setupVrIntent(Intent intent); + + /** * Closes this DaydreamApi instance. */ void close();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java index 26dd86c5..699a2d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java
@@ -130,6 +130,11 @@ } @Override + public Intent setupVrIntent(Intent intent) { + return DaydreamApi.setupVrIntent(intent); + } + + @Override public void close() { if (mDaydreamApi == null) return; mDaydreamApi.close();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrModalPresenter.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrModalPresenter.java index f0510346..346a3e2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrModalPresenter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrModalPresenter.java
@@ -40,4 +40,8 @@ mVrDialogManager.setDialogView(null); mVrDialog = null; } + + public void closeCurrentDialog() { + cancelCurrentDialog(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index a4772470..1f74282 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -178,6 +178,8 @@ // If set to true, we attempt to enter VR mode when the activity is resumed. private boolean mEnterVrOnStartup; + private boolean mInternalIntentUsedToStartVr; + // Set to true if performed VR browsing at least once. That is, this was not simply a WebVr // presentation experience. private boolean mVrBrowserUsed; @@ -238,16 +240,28 @@ // VR before the DON flow), we don't need to add the overlay. if (!sInstance.mInVr) addBlackOverlayViewForActivity(sInstance.mActivity); - // We start the Activity with a custom animation that keeps it hidden while starting - // up to avoid Android showing stale 2D screenshots when the user is in their VR - // headset. The animation lasts up to 10 seconds, but is cancelled when we're - // resumed as at that time we'll be showing the black overlay added above. - int animation = sInstance.mInVr ? 0 : R.anim.stay_hidden; - sInstance.mNeedsAnimationCancel = animation != 0; - Bundle options = - ActivityOptions.makeCustomAnimation(activity, animation, 0).toBundle(); - ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE)) - .moveTaskToFront(activity.getTaskId(), 0, options); + if (activity instanceof ChromeTabbedActivity) { + // We can special case singleInstance activities like CTA to avoid having to use + // moveTaskToFront. Using moveTaskToFront prevents us from disabling window + // animations, and causes the system UI to show up during the preview window and + // window animations. + Intent launchIntent = new Intent(activity, activity.getClass()); + launchIntent = sInstance.mVrDaydreamApi.setupVrIntent(launchIntent); + sInstance.mInternalIntentUsedToStartVr = true; + sInstance.mVrDaydreamApi.launchInVr(PendingIntent.getActivity( + activity, 0, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + // We start the Activity with a custom animation that keeps it hidden while + // starting up to avoid Android showing stale 2D screenshots when the user is in + // their VR headset. The animation lasts up to 10 seconds, but is cancelled when + // we're resumed as at that time we'll be showing the black overlay added above. + int animation = sInstance.mInVr ? 0 : R.anim.stay_hidden; + sInstance.mNeedsAnimationCancel = animation != 0; + Bundle options = + ActivityOptions.makeCustomAnimation(activity, animation, 0).toBundle(); + ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE)) + .moveTaskToFront(activity.getTaskId(), 0, options); + } } else { if (sInstance.mInVrAtChromeLaunch == null) sInstance.mInVrAtChromeLaunch = true; // If a WebVR app calls requestPresent in response to the displayactivate event @@ -996,6 +1010,13 @@ VrShellDelegate instance = getInstance(activity); if (instance == null) return; + + // Nothing to do if we were launched by an internal intent. + if (instance.mInternalIntentUsedToStartVr) { + instance.mInternalIntentUsedToStartVr = false; + return; + } + // TODO(ymalik): We should cache whether or not VR mode is set so we don't set it // needlessly. setVrModeEnabled(activity); @@ -1042,9 +1063,8 @@ */ public static void maybeHandleVrIntentPreNative(ChromeActivity activity, Intent intent) { if (!VrIntentUtils.isVrIntent(intent)) return; - // If we get an intent while we're already in VR, we do nothing. This is mostly - // because crbug.com/780673 since on Android O, every intent gets dispatched twice. - if (sInstance != null && sInstance.mInVr) return; + // If we already have an instance, nothing to do here. + if (sInstance != null) return; if (DEBUG_LOGS) Log.i(TAG, "maybeHandleVrIntentPreNative: preparing for transition"); // We add a black overlay view so that we can show black while the VR UI is loading. // Note that this alone isn't sufficient to prevent 2D UI from showing when
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 6911164f..575e32e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -113,6 +113,7 @@ private VrViewContainer mVrUiViewContainer; private FrameLayout mUiView; private ModalDialogManager mNonVrModalDialogManager; + private VrModalPresenter mVrModalPresenter; public VrShellImpl( ChromeActivity activity, VrShellDelegate delegate, TabModelSelector tabModelSelector) { @@ -273,8 +274,9 @@ if (!ChromeFeatureList.isEnabled(ChromeFeatureList.VR_BROWSING_NATIVE_ANDROID_UI)) return; mNonVrModalDialogManager = mActivity.getModalDialogManager(); mNonVrModalDialogManager.cancelAllDialogs(); + mVrModalPresenter = new VrModalPresenter(this); mActivity.setModalDialogManager( - new ModalDialogManager(new VrModalPresenter(this), ModalDialogManager.APP_MODAL)); + new ModalDialogManager(mVrModalPresenter, ModalDialogManager.APP_MODAL)); ViewGroup decor = (ViewGroup) mActivity.getWindow().getDecorView(); mUiView = new FrameLayout(decor.getContext()); @@ -481,6 +483,12 @@ mDelegate.exitCct(); } + // Close the current hosted Dialog in VR + @CalledByNative + public void closeCurrentDialog() { + mVrModalPresenter.closeCurrentDialog(); + } + @CalledByNative public void setContentCssSize(float width, float height, float dpr) { ThreadUtils.assertOnUiThread();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/CompatibilityTextInputLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/CompatibilityTextInputLayout.java index 8259168..4a9bc32a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/CompatibilityTextInputLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/CompatibilityTextInputLayout.java
@@ -27,6 +27,10 @@ public CompatibilityTextInputLayout(Context context, AttributeSet attrs) { super(context, attrs); + // Disable the hint animation initially to work around a bug in the support library that + // causes the hint text and text in populated EditText views to overlap when first + // displayed on M-. See https://crbug.com/740057. + setHintAnimationEnabled(false); } @Override @@ -47,6 +51,12 @@ } } + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + setHintAnimationEnabled(true); + } + /** * Dig through the descendant hierarchy to find the EditText displayed by this TextInputLayout. * This is necessary because the Support Library version we're using automatically inserts a
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 25984b8..affff7f5 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -227,6 +227,9 @@ <message name="IDS_RETRY" desc="The label for retry button. [CHAR-LIMIT=20]"> Retry </message> + <message name="IDS_TRY_AGAIN" desc="The label for a button allowing the user to try an action again."> + Try again + </message> <!-- Main Preferences --> <message name="IDS_PREFERENCES" desc="Title for Chrome's Settings."> @@ -504,6 +507,21 @@ <message name="IDS_SETTINGS_PASSWORDS_PREPARING_EXPORT" desc="Text shown to the user above a progress bar, informing the user that passwords are being prepared for export."> Preparing passwords… </message> + <message name="IDS_SAVE_PASSWORD_PREFERENCES_EXPORT_ERROR_TITLE" desc="The title of a dialog showing an error encountered during exporting passwords from the passwords settings."> + Can’t export passwords + </message> + <message name="IDS_SAVE_PASSWORD_PREFERENCES_EXPORT_LEARN_GOOGLE_DRIVE" desc="The label of a button in an error dialog after exporting passwords from the settings failed. The button takes the user to a help article about using Google Drive."> + Learn how to use Google Drive + </message> + <message name="IDS_SAVE_PASSWORD_PREFERENCES_EXPORT_NO_APP" desc="The explanation of the error when exporting passwords fails because the user has no Android app installed which could consume the exported data. The description is shown in the body of an alert dialog."> + Your device doesn’t have an app to store the passwords file. + </message> + <message name="IDS_SAVE_PASSWORD_PREFERENCES_EXPORT_TIPS" desc="Tips on how to fix an error with exporting passwords. They are shown in the body of an alert dialog."> + Try the following tips: make sure there is enough space on your device, try to export again. + </message> + <message name="IDS_SAVE_PASSWORD_PREFERENCES_EXPORT_ERROR_DETAILS" desc="A short prefix to introduce a technical error message passed to the user from Android after exporting passwords through a temporary file fails. Both the prefix and the error message are shown in the body of an alert dialog."> + Details: <ph name="ERROR_DESCRIPTION">%1$s<ex>IOException: No space left on device</ex></ph> + </message> <!-- Lock Screen Fragment --> <message name="IDS_LOCKSCREEN_DESCRIPTION_COPY" desc="When a user attempts to copy a password for a particular website into clipboard in Chrome's settings, Chrome launches a lock screen to verify the user's identity and displays the following explanation.">
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 2ebf50b9..ea778b27 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -583,6 +583,7 @@ "java/src/org/chromium/chrome/browser/media/remote/RecordCastAction.java", "java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java", "java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerController.java", + "java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerWrapper.java", "java/src/org/chromium/chrome/browser/media/remote/RemoteVideoInfo.java", "java/src/org/chromium/chrome/browser/media/remote/PositionExtrapolator.java", "java/src/org/chromium/chrome/browser/media/router/BaseMediaRouteDialogManager.java", @@ -985,6 +986,7 @@ "java/src/org/chromium/chrome/browser/preferences/languages/LanguageItem.java", "java/src/org/chromium/chrome/browser/preferences/languages/LanguageListBaseAdapter.java", "java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java", + "java/src/org/chromium/chrome/browser/preferences/password/ExportErrorDialogFragment.java", "java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java", "java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java", "java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 196a448e..f7e15067 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -250,13 +250,26 @@ } /** + * Add a bundle specifying a a number of custom menu entries. + * @param customTabIntent The intent to modify. + * @param numEntries The number of menu entries to add. + * @return The pending intent associated with the menu entries. + */ + private PendingIntent addMenuEntriesToIntent(Intent customTabIntent, int numEntries) { + return addMenuEntriesToIntent(customTabIntent, numEntries, new Intent()); + } + + /** * Add a bundle specifying a custom menu entry. - * @param intent The intent to modify. + * @param customTabIntent The intent to modify. + * @param numEntries The number of menu entries to add. + * @param callbackIntent The intent to use as the base for the pending intent. * @return The pending intent associated with the menu entry. */ - private PendingIntent addMenuEntriesToIntent(Intent intent, int numEntries) { - PendingIntent pi = PendingIntent.getBroadcast( - InstrumentationRegistry.getTargetContext(), 0, new Intent(), 0); + private PendingIntent addMenuEntriesToIntent( + Intent customTabIntent, int numEntries, Intent callbackIntent) { + PendingIntent pi = PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0, + callbackIntent, PendingIntent.FLAG_UPDATE_CURRENT); ArrayList<Bundle> menuItems = new ArrayList<>(); for (int i = 0; i < numEntries; i++) { Bundle bundle = new Bundle(); @@ -264,7 +277,7 @@ bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi); menuItems.add(bundle); } - intent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, menuItems); + customTabIntent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, menuItems); return pi; } @@ -661,9 +674,11 @@ @SmallTest @RetryOnFailure public void testCustomMenuEntry() throws InterruptedException, TimeoutException { - Intent intent = createMinimalCustomTabIntent(); - final PendingIntent pi = addMenuEntriesToIntent(intent, 1); - mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + Intent customTabIntent = createMinimalCustomTabIntent(); + Intent baseCallbackIntent = new Intent(); + baseCallbackIntent.putExtra("FOO", 42); + final PendingIntent pi = addMenuEntriesToIntent(customTabIntent, 1, baseCallbackIntent); + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(customTabIntent); final OnFinishedForTest onFinished = new OnFinishedForTest(pi); getActivity().getIntentDataProvider().setPendingIntentOnFinishedForTesting(onFinished); @@ -677,6 +692,14 @@ }); onFinished.waitForCallback("Pending Intent was not sent."); + Intent callbackIntent = onFinished.getCallbackIntent(); + Assert.assertThat(callbackIntent.getDataString(), equalTo(mTestPage)); + + // Verify that the callback intent has the page title as the subject, but other extras are + // kept intact. + Assert.assertThat( + callbackIntent.getStringExtra(Intent.EXTRA_SUBJECT), equalTo("The Google")); + Assert.assertThat(callbackIntent.getIntExtra("FOO", 0), equalTo(42)); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java index 562ec93c..5b4f151 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
@@ -15,8 +15,10 @@ import static android.support.test.espresso.intent.Intents.intending; import static android.support.test.espresso.intent.matcher.BundleMatchers.hasEntry; import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasData; import static android.support.test.espresso.intent.matcher.IntentMatchers.hasExtras; import static android.support.test.espresso.intent.matcher.IntentMatchers.hasType; +import static android.support.test.espresso.intent.matcher.UriMatchers.hasHost; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.isEnabled; @@ -256,6 +258,23 @@ } /** + * Requests showing an arbitrary password export error. + * @param preferences is the SavePasswordsPreferences instance being tested. + * @param positiveButtonLabelId controls which label the positive button ends up having. + */ + private void requestShowingExportError(Preferences preferences, int positiveButtonLabelId) { + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + SavePasswordsPreferences fragment = + (SavePasswordsPreferences) preferences.getFragmentForTest(); + fragment.showExportErrorAndAbort(R.string.save_password_preferences_export_no_app, + null, positiveButtonLabelId); + } + }); + } + + /** * Call after activity.finish() to wait for the wrap up to complete. If it was already completed * or could be finished within |timeout_ms|, stop waiting anyways. * @param activity The activity to wait for. @@ -757,7 +776,7 @@ // Now pretend that passwords have been serialized. mHandler.getExportCallback().onResult("serialized passwords"); - // Before simulating the serialized passwords being received, check that the progress bar is + // After simulating the serialized passwords being received, check that the progress bar is // hidden. Espresso.onView(withText(R.string.settings_passwords_preparing_export)) .check(doesNotExist()); @@ -812,6 +831,181 @@ } /** + * Check that the user can cancel exporting with the negative button on the error message. + */ + @Test + @SmallTest + @Feature({"Preferences"}) + @EnableFeatures("PasswordExport") + public void testExportCancelOnError() throws Exception { + setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password")); + + ReauthenticationManager.setApiOverride(ReauthenticationManager.OVERRIDE_STATE_AVAILABLE); + ReauthenticationManager.setScreenLockSetUpOverride( + ReauthenticationManager.OVERRIDE_STATE_AVAILABLE); + + final Preferences preferences = + PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), + SavePasswordsPreferences.class.getName()); + + reauthenticateAndRequestExport(); + + // Confirm the export warning. + Espresso.onView(withText(R.string.save_password_preferences_export_action_title)) + .perform(click()); + + // Show an arbitrary error. This should replace the progress bar if that has been shown in + // the meantime. + requestShowingExportError( + preferences, R.string.save_password_preferences_export_learn_google_drive); + + // Check that the error prompt is showing. + Espresso.onView(withText(R.string.save_password_preferences_export_no_app)) + .check(matches(isDisplayed())); + + // Hit the negative button on the error prompt. + Espresso.onView(withText(R.string.close)).perform(click()); + + // Check that the cancellation succeeded by checking that the export menu is available and + // enabled. + openActionBarOverflowOrOptionsMenu( + InstrumentationRegistry.getInstrumentation().getTargetContext()); + // The text matches a text view, but the potentially disabled entity is some wrapper two + // levels up in the view hierarchy, hence the two withParent matchers. + Espresso.onView(allOf(withText(R.string.save_password_preferences_export_action_title), + withParent(withParent(isEnabled())))) + .check(matches(isDisplayed())); + } + + /** + * Check that the user can re-trigger the export from an error dialog which has a "retry" + * button. + */ + @Test + @SmallTest + @Feature({"Preferences"}) + @EnableFeatures("PasswordExport") + public void testExportRetry() throws Exception { + setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password")); + + ReauthenticationManager.setApiOverride(ReauthenticationManager.OVERRIDE_STATE_AVAILABLE); + ReauthenticationManager.setScreenLockSetUpOverride( + ReauthenticationManager.OVERRIDE_STATE_AVAILABLE); + + final Preferences preferences = + PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), + SavePasswordsPreferences.class.getName()); + + reauthenticateAndRequestExport(); + + // Confirm the export warning. + Espresso.onView(withText(R.string.save_password_preferences_export_action_title)) + .perform(click()); + + // Show an arbitrary error but ensure that the positive button label is the one for "try + // again". + requestShowingExportError(preferences, R.string.try_again); + + // Hit the positive button to try again. + Espresso.onView(withText(R.string.try_again)).perform(click()); + + // Check that there is again the export warning. + Espresso.onView(withText(R.string.save_password_preferences_export_action_title)) + .check(matches(isDisplayed())); + } + + /** + * Check that the error dialog lets the user visit a help page to install Google Drive if they + * need an app to consume the exported passwords. + */ + @Test + @SmallTest + @Feature({"Preferences"}) + @EnableFeatures("PasswordExport") + public void testExportHelpSite() throws Exception { + setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password")); + + ReauthenticationManager.setApiOverride(ReauthenticationManager.OVERRIDE_STATE_AVAILABLE); + ReauthenticationManager.setScreenLockSetUpOverride( + ReauthenticationManager.OVERRIDE_STATE_AVAILABLE); + + final Preferences preferences = + PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), + SavePasswordsPreferences.class.getName()); + + reauthenticateAndRequestExport(); + + // Confirm the export warning. + Espresso.onView(withText(R.string.save_password_preferences_export_action_title)) + .perform(click()); + + // Show an arbitrary error but ensure that the positive button label is the one for the + // Google Drive help site. + requestShowingExportError( + preferences, R.string.save_password_preferences_export_learn_google_drive); + + Intents.init(); + + // Before triggering the viewing intent, stub it out to avoid cascading that into further + // intents and opening the web browser. + intending(hasAction(equalTo(Intent.ACTION_VIEW))) + .respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, null)); + + // Hit the positive button to navigate to the help site. + Espresso.onView(withText(R.string.save_password_preferences_export_learn_google_drive)) + .perform(click()); + + intended(allOf(hasAction(equalTo(Intent.ACTION_VIEW)), + hasData(hasHost(equalTo("support.google.com"))))); + + Intents.release(); + } + + /** + * Check that if errors are encountered when user is busy confirming the export, the error UI is + * shown after the confirmation is completed, so that the user does not see UI changing + * unexpectedly under their fingers. + */ + @Test + @SmallTest + @Feature({"Preferences"}) + @EnableFeatures("PasswordExport") + public void testExportErrorUiAfterConfirmation() throws Exception { + setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password")); + + ReauthenticationManager.setApiOverride(ReauthenticationManager.OVERRIDE_STATE_AVAILABLE); + ReauthenticationManager.setScreenLockSetUpOverride( + ReauthenticationManager.OVERRIDE_STATE_AVAILABLE); + + final Preferences preferences = + PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), + SavePasswordsPreferences.class.getName()); + + reauthenticateAndRequestExport(); + + // Request showing an arbitrary error while the confirmation dialog is still up. + requestShowingExportError( + preferences, R.string.save_password_preferences_export_learn_google_drive); + + // Check that the confirmation dialog is showing and dismiss it. + Espresso.onView(withText(R.string.save_password_preferences_export_action_title)) + .perform(click()); + + // Check that now the error is displayed, instead of the progress bar. + Espresso.onView(withText(R.string.settings_passwords_preparing_export)) + .check(doesNotExist()); + Espresso.onView(withText(R.string.save_password_preferences_export_no_app)) + .check(matches(isDisplayed())); + + // Close the error dialog and abort the export. + Espresso.onView(withText(R.string.close)).perform(click()); + + // Ensure that there is still no progress bar. + Espresso.onView(withText(R.string.settings_passwords_preparing_export)) + .check(doesNotExist()); + } + + /** * Check whether the user is asked to set up a screen lock if attempting to view passwords. */ @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java index 6431ab3..a8136f65 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java
@@ -85,4 +85,9 @@ @Override public void close() {} + + @Override + public Intent setupVrIntent(Intent intent) { + return null; + } }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 9003dc1..ee969e7 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -497,8 +497,8 @@ <message name="IDS_CONTENT_CONTEXT_OPENAUDIONEWTAB" desc="The name of the Open Audio in New Tab command in the content area context menu"> &Open audio in new tab </message> - <message name="IDS_CONTENT_CONTENT_PICTUREINPICTURE" desc="The name of the Picture in Picture command in the content area context menu."> - Picture in Picture + <message name="IDS_CONTENT_CONTENT_PICTUREINPICTURE" desc="The name of the Picture-in-Picture command in the content area context menu."> + Picture-in-Picture </message> <message name="IDS_CONTENT_CONTEXT_UNDO" desc="The name of the Undo command in the content area context menu"> @@ -703,8 +703,8 @@ <message name="IDS_CONTENT_CONTEXT_OPENAUDIONEWTAB" desc="In Title Case: The name of the Open Audio in New Tab command in the content area context menu"> &Open Audio in New Tab </message> - <message name="IDS_CONTENT_CONTENT_PICTUREINPICTURE" desc="In Title Case: The name of the Picture in Picture command in the content area context menu."> - Picture in Picture + <message name="IDS_CONTENT_CONTENT_PICTUREINPICTURE" desc="In Title Case: The name of the Picture-in-Picture command in the content area context menu."> + Picture-in-Picture </message> <message name="IDS_CONTENT_CONTEXT_UNDO" desc="In Title Case: The name of the Undo command in the content area context menu"> @@ -6061,9 +6061,9 @@ Turn on autoupdate </message> - <!-- Picture in Picture --> - <message name="IDS_PICTURE_IN_PICTURE_TITLE_TEXT" desc="Title of the picture in picture window. This appears in the system tray and window header."> - Picture in Picture + <!-- Picture-in-Picture --> + <message name="IDS_PICTURE_IN_PICTURE_TITLE_TEXT" desc="Title of the picture-in-picture window. This appears in the system tray and window header."> + Picture-in-Picture </message> <!-- Print -->
diff --git a/chrome/app/vector_icons/ads.icon b/chrome/app/vector_icons/ads.icon index 35542192..36effc4 100644 --- a/chrome/app/vector_icons/ads.icon +++ b/chrome/app/vector_icons/ads.icon
@@ -2,41 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 18, -MOVE_TO, 4, 3, -R_H_LINE_TO, 10, -R_ARC_TO, 2, 2, 0, 0, 1, 2, 2, +CANVAS_DIMENSIONS, 16, +MOVE_TO, 4, 2, +R_ARC_TO, 2, 2, 0, 0, 0, -2, 2, R_V_LINE_TO, 8, -R_ARC_TO, 2, 2, 0, 0, 1, -2, 2, +R_ARC_TO, 2, 2, 0, 0, 0, 2, 2, +R_H_LINE_TO, 8, +R_ARC_TO, 2, 2, 0, 0, 0, 2, -2, +V_LINE_TO, 4, +R_ARC_TO, 2, 2, 0, 0, 0, -2, -2, H_LINE_TO, 4, -R_ARC_TO, 2, 2, 0, 0, 1, -2, -2, -V_LINE_TO, 5, -R_ARC_TO, 2, 2, 0, 0, 1, 2, -2, CLOSE, -R_MOVE_TO, 6, 3, -R_V_LINE_TO, 6, -R_H_LINE_TO, 3, -R_ARC_TO, 1, 1, 0, 0, 0, 1, -1, -V_LINE_TO, 7, -R_ARC_TO, 1, 1, 0, 0, 0, -1, -1, -CLOSE, -R_MOVE_TO, 1, 1, -R_H_LINE_TO, 2, -R_V_LINE_TO, 4, -R_H_LINE_TO, -2, -CLOSE, -MOVE_TO, 4, 6, -R_V_LINE_TO, 6, -R_H_LINE_TO, 1, -R_V_LINE_TO, -2, -R_H_LINE_TO, 2, -R_V_LINE_TO, 2, -R_H_LINE_TO, 1, +R_MOVE_TO, 8, 10, +H_LINE_TO, 4, V_LINE_TO, 6, -CLOSE, -R_MOVE_TO, 1, 1, -R_H_LINE_TO, 2, -R_V_LINE_TO, 2, -H_LINE_TO, 5, +R_H_LINE_TO, 8, +R_V_LINE_TO, 6, CLOSE, END
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index c57b5807..26e2a0370 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4538,6 +4538,13 @@ "//chrome/browser/resources/md_downloads:build", "//chrome/browser/resources/md_history:build", ] + if (is_chromeos) { + deps += [ + "//chrome/browser/resources/chromeos/bluetooth_pairing_dialog:build", + "//chrome/browser/resources/chromeos/internet_config_dialog:build", + "//chrome/browser/resources/chromeos/internet_detail_dialog:build", + ] + } } if (safe_browsing_mode > 0) {
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc index dfa670f..f6edc0e 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.cc +++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -196,6 +196,13 @@ FROM_HERE, base::Bind(&VrShell::ExitCct, weak_vr_shell_)); } +void VrGLThread::CloseHostedDialog() { + DCHECK(OnGlThread()); + main_thread_task_runner_->PostTask( + FROM_HERE, + base::BindRepeating(&VrShell::CloseHostedDialog, weak_vr_shell_)); +} + void VrGLThread::ToggleCardboardGamepad(bool enabled) { DCHECK(OnGlThread()); main_thread_task_runner_->PostTask(
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.h b/chrome/browser/android/vr_shell/vr_gl_thread.h index 3f6fecf..628fd196 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.h +++ b/chrome/browser/android/vr_shell/vr_gl_thread.h
@@ -74,6 +74,7 @@ void Navigate(GURL gurl) override; void NavigateBack() override; void ExitCct() override; + void CloseHostedDialog() override; void OnUnsupportedMode(vr::UiUnsupportedMode mode) override; void OnExitVrPromptResult(vr::ExitVrPromptChoice choice, vr::UiUnsupportedMode reason) override;
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc index 5df0a580..751558c0 100644 --- a/chrome/browser/android/vr_shell/vr_shell.cc +++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -320,6 +320,11 @@ Java_VrShellImpl_exitCct(env, j_vr_shell_); } +void VrShell::CloseHostedDialog() { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_VrShellImpl_closeCurrentDialog(env, j_vr_shell_); +} + void VrShell::ToggleCardboardGamepad(bool enabled) { // Enable/disable updating gamepad state. if (cardboard_gamepad_source_active_ && !enabled) {
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h index 66ada9bf..6f4819d 100644 --- a/chrome/browser/android/vr_shell/vr_shell.h +++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -136,6 +136,7 @@ void Navigate(GURL url); void NavigateBack(); void ExitCct(); + void CloseHostedDialog(); void ToggleCardboardGamepad(bool enabled); void ToggleGvrGamepad(bool enabled); void SetHistoryButtonsEnabled(JNIEnv* env,
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 8d7bfc8..82ed106 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -145,7 +145,6 @@ #if !defined(OS_ANDROID) #include "chrome/browser/gcm/gcm_product_util.h" -#include "chrome/browser/ui/user_manager.h" #include "components/gcm_driver/gcm_client_factory.h" #include "components/gcm_driver/gcm_desktop_utils.h" #include "components/keep_alive_registry/keep_alive_registry.h" @@ -178,6 +177,7 @@ #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #include "chrome/browser/first_run/upgrade_util.h" +#include "chrome/browser/ui/user_manager.h" #endif #if defined(OS_ANDROID) @@ -322,9 +322,7 @@ tearing_down_ = true; DCHECK(IsShuttingDown()); -#if !defined(OS_ANDROID) KeepAliveRegistry::GetInstance()->SetIsShuttingDown(); -#endif // !defined(OS_ANDROID) // We need to destroy the MetricsServicesManager, IntranetRedirectDetector, // NetworkTimeTracker, and SafeBrowsing ClientSideDetectionService @@ -358,9 +356,11 @@ { TRACE_EVENT0("shutdown", "BrowserProcessImpl::StartTearDown:ProfileManager"); +#if !defined(OS_CHROMEOS) // The desktop User Manager needs to be closed before the guest profile // can be destroyed. UserManager::Hide(); +#endif // !defined(OS_CHROMEOS) profile_manager_.reset(); }
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 6fa36ef..b175d94 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -441,8 +441,16 @@ <include name="IDR_CRYPTOTOKEN_MANIFEST" file="resources\cryptotoken\manifest.json" type="BINDATA" /> <include name="IDR_GAIA_AUTH_MANIFEST" file="resources\gaia_auth\manifest.json" type="BINDATA" /> <if expr="chromeos"> - <include name="IDR_BLUETOOTH_PAIRING_DIALOG_HTML" file="resources\chromeos\bluetooth_pairing_dialog.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> - <include name="IDR_BLUETOOTH_PAIRING_DIALOG_JS" file="resources\chromeos\bluetooth_pairing_dialog.js" type="chrome_html" /> + <if expr="optimize_webui"> + <then> + <include name="IDR_BLUETOOTH_PAIRING_DIALOG_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\chromeos\bluetooth_pairing_dialog\vulcanized.html" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> + <include name="IDR_BLUETOOTH_PAIRING_DIALOG_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\bluetooth_pairing_dialog\crisper.js" use_base_dir="false" flattenhtml="true" type="BINDATA" compress="gzip" /> + </then> + <else> + <include name="IDR_BLUETOOTH_PAIRING_DIALOG_HTML" file="resources\chromeos\bluetooth_pairing_dialog\bluetooth_pairing_dialog.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> + <include name="IDR_BLUETOOTH_PAIRING_DIALOG_JS" file="resources\chromeos\bluetooth_pairing_dialog\bluetooth_pairing_dialog.js" type="chrome_html" /> + </else> + </if> <include name="IDR_CROSH_BUILTIN_MANIFEST" file="resources\chromeos\crosh_builtin\manifest.json" type="BINDATA" /> <include name="IDR_CRYPTOHOME_HTML" file="resources\chromeos\cryptohome.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_CRYPTOHOME_JS" file="resources\chromeos\cryptohome.js" type="BINDATA" /> @@ -462,10 +470,20 @@ <include name="IDR_ECHO_MANIFEST" file="resources\chromeos\echo\manifest.json" type="BINDATA" /> <include name="IDR_MERGE_SESSION_LOAD_HTML" file="resources\chromeos\merge_session_load.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_OS_CREDITS_HTML" file="resources\chromeos\about_os_credits.html" flattenhtml="true" type="BINDATA" /> - <include name="IDR_INTERNET_CONFIG_DIALOG_HTML" file="resources\chromeos\internet_config_dialog.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> - <include name="IDR_INTERNET_CONFIG_DIALOG_JS" file="resources\chromeos\internet_config_dialog.js" type="chrome_html" /> - <include name="IDR_INTERNET_DETAIL_DIALOG_HTML" file="resources\chromeos\internet_detail_dialog.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> - <include name="IDR_INTERNET_DETAIL_DIALOG_JS" file="resources\chromeos\internet_detail_dialog.js" type="chrome_html" /> + <if expr="optimize_webui"> + <then> + <include name="IDR_INTERNET_CONFIG_DIALOG_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\chromeos\internet_config_dialog\vulcanized.html" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> + <include name="IDR_INTERNET_CONFIG_DIALOG_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\internet_config_dialog\crisper.js" use_base_dir="false" flattenhtml="true" type="BINDATA" compress="gzip" /> + <include name="IDR_INTERNET_DETAIL_DIALOG_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\chromeos\internet_detail_dialog\vulcanized.html" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> + <include name="IDR_INTERNET_DETAIL_DIALOG_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\internet_detail_dialog\crisper.js" use_base_dir="false" flattenhtml="true" type="BINDATA" compress="gzip" /> + </then> + <else> + <include name="IDR_INTERNET_CONFIG_DIALOG_HTML" file="resources\chromeos\internet_config_dialog\internet_config_dialog.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> + <include name="IDR_INTERNET_CONFIG_DIALOG_JS" file="resources\chromeos\internet_config_dialog\internet_config_dialog.js" type="chrome_html" /> + <include name="IDR_INTERNET_DETAIL_DIALOG_HTML" file="resources\chromeos\internet_detail_dialog\internet_detail_dialog.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> + <include name="IDR_INTERNET_DETAIL_DIALOG_JS" file="resources\chromeos\internet_detail_dialog\internet_detail_dialog.js" type="chrome_html" /> + </else> + </if> <include name="IDR_CERT_MANAGER_DIALOG_HTML" file="resources\chromeos\certificate_manager_dialog.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_SLOW_HTML" file="resources\chromeos\slow.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_SLOW_JS" file="resources\chromeos\slow.js" type="BINDATA" />
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index b3c5edc..2b63a36 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -975,6 +975,13 @@ g_browser_process->metrics_service()->CheckForClonedInstall(); +#if defined(OS_WIN) + // The last live timestamp is used to assess whether a browser crash occurred + // due to a full system crash. Update the last live timestamp on a slow + // schedule to get the bast possible accuracy for the assessment. + g_browser_process->metrics_service()->StartUpdatingLastLiveTimestamp(); +#endif + // Register a synthetic field trial for the sampling profiler configuration // that was already chosen. std::string trial_name, group_name;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c55d2143..aa2beb24 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3707,7 +3707,8 @@ const network::ResourceRequest& request, content::ResourceContext* resource_context, const base::RepeatingCallback<content::WebContents*()>& wc_getter, - content::NavigationUIData* navigation_ui_data) { + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); bool network_service_enabled = @@ -3718,8 +3719,10 @@ if (network_service_enabled || base::FeatureList::IsEnabled(safe_browsing::kCheckByURLLoaderThrottle)) { auto* delegate = GetSafeBrowsingUrlCheckerDelegate(resource_context); - if (delegate && - !delegate->ShouldSkipRequestCheck(resource_context, request.url)) { + if (delegate && !delegate->ShouldSkipRequestCheck( + resource_context, request.url, frame_tree_node_id, + -1 /* render_process_id */, -1 /* render_frame_id */, + request.originated_from_service_worker)) { auto safe_browsing_throttle = safe_browsing::BrowserURLLoaderThrottle::MaybeCreate(delegate, wc_getter);
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index d175da4..16abb56 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -380,7 +380,8 @@ const network::ResourceRequest& request, content::ResourceContext* resource_context, const base::RepeatingCallback<content::WebContents*()>& wc_getter, - content::NavigationUIData* navigation_ui_data) override; + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id) override; void RegisterNonNetworkNavigationURLLoaderFactories( content::RenderFrameHost* frame_host, NonNetworkURLLoaderFactoryMap* factories) override;
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc index 07bdf5d9..1f50fc92 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc
@@ -530,10 +530,9 @@ void ArcVoiceInteractionFrameworkService::StartVoiceInteractionOobe() { if (chromeos::LoginDisplayHost::default_host()) return; - gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size())); // The display host will be destructed at the end of OOBE flow. chromeos::LoginDisplayHostWebUI* display_host = - new chromeos::LoginDisplayHostWebUI(screen_bounds); + new chromeos::LoginDisplayHostWebUI(); display_host->StartVoiceInteractionOobe(); }
diff --git a/chrome/browser/chromeos/extensions/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc b/chrome/browser/chromeos/extensions/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc index 3dab828f..37b5e1db 100644 --- a/chrome/browser/chromeos/extensions/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc +++ b/chrome/browser/chromeos/extensions/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc
@@ -78,8 +78,8 @@ net::LOAD_DO_NOT_SEND_AUTH_DATA); backdrop::GetCollectionsRequest request; - // TODO(crbug.com/800945): Supports all languages. - request.set_language("en"); + // The language field may include the country code (e.g. "en-US"). + request.set_language(g_browser_process->GetApplicationLocale()); std::string serialized_proto; request.SerializeToString(&serialized_proto); url_fetcher_->SetUploadData(kProtoMimeType, serialized_proto); @@ -170,8 +170,8 @@ net::LOAD_DO_NOT_SEND_AUTH_DATA); backdrop::GetImagesInCollectionRequest request; - // TODO(crbug.com/800945): Supports all languages. - request.set_language("en"); + // The language field may include the country code (e.g. "en-US"). + request.set_language(g_browser_process->GetApplicationLocale()); request.set_collection_id(collection_id_); std::string serialized_proto; request.SerializeToString(&serialized_proto);
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc index 6d80317..a0bc3922 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -194,8 +194,7 @@ ShouldShowSigninScreen(first_screen)) { display_host = new chromeos::LoginDisplayHostViews(); } else { - gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size())); - display_host = new chromeos::LoginDisplayHostWebUI(screen_bounds); + display_host = new chromeos::LoginDisplayHostWebUI(); } // Restore system timezone. @@ -405,10 +404,9 @@ //////////////////////////////////////////////////////////////////////////////// // LoginDisplayHostWebUI, public -LoginDisplayHostWebUI::LoginDisplayHostWebUI(const gfx::Rect& wallpaper_bounds) - : wallpaper_bounds_(wallpaper_bounds), - oobe_startup_sound_played_(StartupUtils::IsOobeCompleted()), - animation_weak_ptr_factory_(this) { +LoginDisplayHostWebUI::LoginDisplayHostWebUI() + : oobe_startup_sound_played_(StartupUtils::IsOobeCompleted()), + weak_factory_(this) { if (ash_util::IsRunningInMash()) { // Animation, and initializing hidden, are not currently supported for Mash. finalize_animation_type_ = ANIMATION_NONE; @@ -477,7 +475,7 @@ media::SoundsManager* manager = media::SoundsManager::Get(); ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - manager->Initialize(chromeos::SOUND_STARTUP, + manager->Initialize(SOUND_STARTUP, bundle.GetRawDataResource(IDR_SOUND_STARTUP_WAV)); } @@ -637,7 +635,7 @@ } existing_user_controller_.reset(); // Only one controller in a time. - existing_user_controller_.reset(new chromeos::ExistingUserController(this)); + existing_user_controller_.reset(new ExistingUserController(this)); if (!signin_screen_controller_.get()) { signin_screen_controller_.reset( @@ -689,7 +687,7 @@ DVLOG(1) << "Starting sign in screen"; existing_user_controller_.reset(); // Only one controller in a time. - existing_user_controller_.reset(new chromeos::ExistingUserController(this)); + existing_user_controller_.reset(new ExistingUserController(this)); if (!signin_screen_controller_.get()) { signin_screen_controller_.reset( @@ -938,7 +936,7 @@ ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); animation.AddObserver(new AnimationObserver( base::Bind(&LoginDisplayHostWebUI::ShutdownDisplayHost, - animation_weak_ptr_factory_.GetWeakPtr()))); + weak_factory_.GetWeakPtr()))); animation.SetTransitionDuration( base::TimeDelta::FromMilliseconds(animation_speed_ms)); layer->SetOpacity(0); @@ -1012,7 +1010,7 @@ views::Widget::InitParams params( views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - params.bounds = wallpaper_bounds(); + params.bounds = CalculateScreenBounds(gfx::Size()); // Disable fullscreen state for voice interaction OOBE since the shelf should // be visible. if (!is_voice_interaction_oobe_) @@ -1131,7 +1129,7 @@ // static void LoginDisplayHostWebUI::DisableRestrictiveProxyCheckForTest() { - static_cast<chromeos::LoginDisplayHostWebUI*>(default_host()) + static_cast<LoginDisplayHostWebUI*>(default_host()) ->GetOobeUI() ->GetGaiaScreenView() ->DisableRestrictiveProxyCheckForTest(); @@ -1140,7 +1138,7 @@ void LoginDisplayHostWebUI::StartVoiceInteractionOobe() { is_voice_interaction_oobe_ = true; finalize_animation_type_ = ANIMATION_NONE; - StartWizard(chromeos::OobeScreen::SCREEN_VOICE_INTERACTION_VALUE_PROP); + StartWizard(OobeScreen::SCREEN_VOICE_INTERACTION_VALUE_PROP); // We should emit this signal only at login screen (after reboot or sign out). login_view_->set_should_emit_login_prompt_visible(false); } @@ -1164,8 +1162,8 @@ VLOG(1) << "Showing OOBE screen: " << GetOobeScreenName(first_screen); - chromeos::input_method::InputMethodManager* manager = - chromeos::input_method::InputMethodManager::Get(); + input_method::InputMethodManager* manager = + input_method::InputMethodManager::Get(); // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty // and US dvorak keyboard layouts. @@ -1184,8 +1182,6 @@ base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kNaturalScrollDefault)); - gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size())); - session_manager::SessionManager::Get()->SetSessionState( StartupUtils::IsOobeCompleted() ? session_manager::SessionState::LOGIN_PRIMARY @@ -1199,7 +1195,7 @@ const bool diagnostic_mode = false; const bool auto_launch = true; // Manages its own lifetime. See ShutdownDisplayHost(). - auto* display_host = new LoginDisplayHostWebUI(screen_bounds); + auto* display_host = new LoginDisplayHostWebUI(); display_host->StartAppLaunch(auto_launch_app_id, diagnostic_mode, auto_launch); return; @@ -1213,7 +1209,7 @@ if (enrollment_config.should_enroll() && first_screen == OobeScreen::SCREEN_UNKNOWN) { // Manages its own lifetime. See ShutdownDisplayHost(). - auto* display_host = new LoginDisplayHostWebUI(screen_bounds); + auto* display_host = new LoginDisplayHostWebUI(); // Shows networks screen instead of enrollment screen to resume the // interrupted auto start enrollment flow because enrollment screen does // not handle flaky network. See http://crbug.com/332572
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.h b/chrome/browser/chromeos/login/ui/login_display_host_webui.h index afb0310..3198e52 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_webui.h +++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
@@ -50,7 +50,7 @@ public views::WidgetRemovalsObserver, public MultiUserWindowManager::Observer { public: - explicit LoginDisplayHostWebUI(const gfx::Rect& wallpaper_bounds); + LoginDisplayHostWebUI(); ~LoginDisplayHostWebUI() override; // LoginDisplayHost: @@ -78,8 +78,6 @@ // Creates WizardController instance. WizardController* CreateWizardController(); - const gfx::Rect& wallpaper_bounds() const { return wallpaper_bounds_; } - // Trace id for ShowLoginWebUI event (since there exists at most one login // WebUI at a time). static const int kShowLoginWebUIid; @@ -174,9 +172,6 @@ // Called when login-prompt-visible signal is caught. void OnLoginPromptVisible(); - // Used to calculate position of the screens and wallpaper. - gfx::Rect wallpaper_bounds_; - // Sign in screen controller. std::unique_ptr<ExistingUserController> existing_user_controller_; @@ -251,7 +246,7 @@ bool is_voice_interaction_oobe_ = false; - base::WeakPtrFactory<LoginDisplayHostWebUI> animation_weak_ptr_factory_; + base::WeakPtrFactory<LoginDisplayHostWebUI> weak_factory_; DISALLOW_COPY_AND_ASSIGN(LoginDisplayHostWebUI); };
diff --git a/chrome/browser/chromeos/login/ui/user_adding_screen.cc b/chrome/browser/chromeos/login/ui/user_adding_screen.cc index 8a5a51b..7b86c58e 100644 --- a/chrome/browser/chromeos/login/ui/user_adding_screen.cc +++ b/chrome/browser/chromeos/login/ui/user_adding_screen.cc
@@ -49,8 +49,7 @@ void UserAddingScreenImpl::Start() { CHECK(!IsRunning()); - gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size())); - display_host_ = new chromeos::LoginDisplayHostWebUI(screen_bounds); + display_host_ = new chromeos::LoginDisplayHostWebUI(); display_host_->StartUserAdding(base::BindOnce( &UserAddingScreenImpl::OnDisplayHostCompletion, base::Unretained(this)));
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 167a64f..4da2041 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -581,23 +581,7 @@ } void WizardController::ShowSyncConsentScreen() { -#if defined(GOOGLE_CHROME_BUILD) - const user_manager::UserManager* user_manager = - user_manager::UserManager::Get(); - // Skip for non-regular users. - if (user_manager->IsLoggedInAsPublicAccount() || - (user_manager->IsCurrentUserNonCryptohomeDataEphemeral() && - user_manager->GetActiveUser()->GetType() != - user_manager::USER_TYPE_REGULAR)) { - ShowArcTermsOfServiceScreen(); - return; - } - VLOG(1) << "Showing Sync Consent screen."; - UpdateStatusAreaVisibilityForScreen(OobeScreen::SCREEN_SYNC_CONSENT); - SetCurrentScreen(GetScreen(OobeScreen::SCREEN_SYNC_CONSENT)); -#else ShowArcTermsOfServiceScreen(); -#endif } void WizardController::ShowArcTermsOfServiceScreen() { @@ -891,7 +875,9 @@ } void WizardController::OnTermsOfServiceAccepted() { - ShowSyncConsentScreen(); + // If the user accepts the Terms of Service, advance to the PlayStore terms + // of serice. + ShowArcTermsOfServiceScreen(); } void WizardController::OnArcTermsOfServiceSkipped() {
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc index 4a4782b..5bb9b3d 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -910,38 +910,38 @@ EXPECT_EQ( CONTENT_SETTING_ASK, host_content_settings_map->GetContentSetting( - host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); + host, host, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string())); EXPECT_EQ( CONTENT_SETTING_ASK, otr_map->GetContentSetting( - host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); + host, host, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string())); // BLOCK should be inherited from the main map to the incognito map. host_content_settings_map->SetContentSettingDefaultScope( - host, GURL(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string(), + host, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string(), CONTENT_SETTING_BLOCK); EXPECT_EQ( CONTENT_SETTING_BLOCK, host_content_settings_map->GetContentSetting( - host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); + host, host, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string())); EXPECT_EQ( CONTENT_SETTING_BLOCK, otr_map->GetContentSetting( - host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); + host, host, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string())); // ALLOW should not be inherited from the main map to the incognito map (but // it still overwrites the BLOCK, hence incognito reverts to ASK). host_content_settings_map->SetContentSettingDefaultScope( - host, GURL(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string(), + host, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string(), CONTENT_SETTING_ALLOW); EXPECT_EQ( CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( - host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); + host, host, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string())); EXPECT_EQ( CONTENT_SETTING_ASK, otr_map->GetContentSetting( - host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); + host, host, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string())); } TEST_F(HostContentSettingsMapTest, IncognitoPartialInheritDefault) {
diff --git a/chrome/browser/extensions/api/DEPS b/chrome/browser/extensions/api/DEPS index fea8d34..e6dcb24 100644 --- a/chrome/browser/extensions/api/DEPS +++ b/chrome/browser/extensions/api/DEPS
@@ -8,7 +8,7 @@ # Enable remote assistance on Chrome OS "+remoting/base", "+remoting/host", - "+services/network/public/interfaces", + "+services/network", ] specific_include_rules = {
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc index d1e636c..6466d63 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -226,8 +226,9 @@ if (event_name) { std::unique_ptr<base::ListValue> args(new base::ListValue()); - args->Append( - ExtensionTabUtil::CreateTabObject(web_contents, extension)->ToValue()); + args->Append(ExtensionTabUtil::CreateTabObject( + web_contents, ExtensionTabUtil::kScrubTab, extension) + ->ToValue()); DispatchEventToExtension(web_contents->GetBrowserContext(), extension_action.extension_id(), histogram_value,
diff --git a/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc b/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc index eeaa819..37f434a3 100644 --- a/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc +++ b/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc
@@ -82,7 +82,13 @@ // Only the tab id is useful to platform apps for internal use. The // unnecessary bits will be stripped out in // MessagingBindings::DispatchOnConnect(). - return ExtensionTabUtil::CreateTabObject(web_contents)->ToValue(); + // Note: We don't bother scrubbing the tab object, because this is only + // reached as a result of a tab (or content script) messaging the extension. + // We need the extension to see the sender so that it can validate if it + // trusts it or not. + return ExtensionTabUtil::CreateTabObject( + web_contents, ExtensionTabUtil::kDontScrubTab, nullptr) + ->ToValue(); } return nullptr; }
diff --git a/chrome/browser/extensions/api/sessions/sessions_api.cc b/chrome/browser/extensions/api/sessions/sessions_api.cc index a575a4c..872c24eb 100644 --- a/chrome/browser/extensions/api/sessions/sessions_api.cc +++ b/chrome/browser/extensions/api/sessions/sessions_api.cc
@@ -381,8 +381,8 @@ ExtensionFunction::ResponseValue SessionsRestoreFunction::GetRestoredTabResult( content::WebContents* contents) { - std::unique_ptr<tabs::Tab> tab( - ExtensionTabUtil::CreateTabObject(contents, extension())); + std::unique_ptr<tabs::Tab> tab(ExtensionTabUtil::CreateTabObject( + contents, ExtensionTabUtil::kScrubTab, extension())); std::unique_ptr<api::sessions::Session> restored_session( CreateSessionModelHelper(base::Time::Now().ToTimeT(), std::move(tab), std::unique_ptr<windows::Window>()));
diff --git a/chrome/browser/extensions/api/socket/udp_socket_unittest.cc b/chrome/browser/extensions/api/socket/udp_socket_unittest.cc index 27fd028..c9150a6 100644 --- a/chrome/browser/extensions/api/socket/udp_socket_unittest.cc +++ b/chrome/browser/extensions/api/socket/udp_socket_unittest.cc
@@ -15,17 +15,37 @@ #include "base/single_thread_task_runner.h" #include "base/test/test_timeouts.h" #include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/extensions/extension_service_test_base.h" #include "chrome/test/base/browser_with_test_window_test.h" +#include "content/public/browser/storage_partition.h" #include "extensions/browser/api/socket/udp_socket.h" #include "net/base/io_buffer.h" #include "net/base/ip_address.h" +#include "net/base/test_completion_callback.h" +#include "services/network/network_context.h" +#include "services/network/public/interfaces/udp_socket.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace extensions { -// UDPSocketUnitTest exists solely to make it easier to pass a specific -// gtest_filter argument during development. -class UDPSocketUnitTest : public BrowserWithTestWindowTest { +class UDPSocketUnitTest : public extensions::ExtensionServiceTestBase { + protected: + // extensions::ExtensionServiceTestBase: + void SetUp() override { InitializeEmptyExtensionService(); } + + std::unique_ptr<UDPSocket> CreateSocket() { + network::mojom::NetworkContext* network_context = + content::BrowserContext::GetDefaultStoragePartition(profile()) + ->GetNetworkContext(); + network::mojom::UDPSocketPtrInfo socket; + network::mojom::UDPSocketReceiverPtr receiver_ptr; + network::mojom::UDPSocketReceiverRequest receiver_request = + mojo::MakeRequest(&receiver_ptr); + network_context->CreateUDPSocket(mojo::MakeRequest(&socket), + std::move(receiver_ptr)); + return std::make_unique<UDPSocket>( + std::move(socket), std::move(receiver_request), "abcdefghijklmnopqrst"); + } }; static void OnConnected(int result) { @@ -40,8 +60,8 @@ // Do nothing; don't care. } -static const char test_message[] = "$$TESTMESSAGETESTMESSAGETESTMESSAGETEST$$"; -static const int test_message_length = arraysize(test_message); +static const char kTestMessage[] = "$$TESTMESSAGETESTMESSAGETESTMESSAGETEST$$"; +static const int kTestMessageLength = arraysize(kTestMessage); net::AddressList CreateAddressList(const char* address_string, int port) { net::IPAddress ip; @@ -50,50 +70,69 @@ } static void OnSendCompleted(int result) { - EXPECT_EQ(test_message_length, result); + EXPECT_EQ(kTestMessageLength, result); } -TEST(UDPSocketUnitTest, TestUDPSocketRecvFrom) { - base::MessageLoopForIO io_loop; // For RecvFrom to do its threaded work. - UDPSocket socket("abcdefghijklmnopqrst"); +TEST_F(UDPSocketUnitTest, TestUDPSocketRecvFrom) { + std::unique_ptr<UDPSocket> socket = CreateSocket(); // Confirm that we can call two RecvFroms in quick succession without // triggering crbug.com/146606. - socket.Connect(CreateAddressList("127.0.0.1", 40000), - base::Bind(&OnConnected)); - socket.RecvFrom(4096, base::Bind(&OnCompleted)); - socket.RecvFrom(4096, base::Bind(&OnCompleted)); + socket->Connect(CreateAddressList("127.0.0.1", 40000), + base::BindRepeating(&OnConnected)); + socket->RecvFrom(4096, base::BindRepeating(&OnCompleted)); + socket->RecvFrom(4096, base::BindRepeating(&OnCompleted)); } -TEST(UDPSocketUnitTest, TestUDPMulticastJoinGroup) { +TEST_F(UDPSocketUnitTest, TestUDPMulticastJoinGroup) { const char kGroup[] = "237.132.100.17"; - UDPSocket src("abcdefghijklmnopqrst"); - UDPSocket dest("abcdefghijklmnopqrst"); + std::unique_ptr<UDPSocket> src = CreateSocket(); + std::unique_ptr<UDPSocket> dest = CreateSocket(); - EXPECT_EQ(0, dest.Bind("0.0.0.0", 13333)); - EXPECT_EQ(0, dest.JoinGroup(kGroup)); - std::vector<std::string> groups = dest.GetJoinedGroups(); + { + net::TestCompletionCallback callback; + dest->Bind("0.0.0.0", 13333, callback.callback()); + EXPECT_EQ(net::OK, callback.WaitForResult()); + } + { + net::TestCompletionCallback callback; + dest->JoinGroup(kGroup, callback.callback()); + EXPECT_EQ(net::OK, callback.WaitForResult()); + } + std::vector<std::string> groups = dest->GetJoinedGroups(); EXPECT_EQ(static_cast<size_t>(1), groups.size()); EXPECT_EQ(kGroup, *groups.begin()); - EXPECT_NE(0, dest.LeaveGroup("237.132.100.13")); - EXPECT_EQ(0, dest.LeaveGroup(kGroup)); - groups = dest.GetJoinedGroups(); + { + net::TestCompletionCallback callback; + dest->LeaveGroup("237.132.100.13", callback.callback()); + EXPECT_NE(net::OK, callback.WaitForResult()); + } + { + net::TestCompletionCallback callback; + dest->LeaveGroup(kGroup, callback.callback()); + EXPECT_EQ(net::OK, callback.WaitForResult()); + } + groups = dest->GetJoinedGroups(); EXPECT_EQ(static_cast<size_t>(0), groups.size()); } -TEST(UDPSocketUnitTest, TestUDPMulticastTimeToLive) { +TEST_F(UDPSocketUnitTest, TestUDPMulticastTimeToLive) { const char kGroup[] = "237.132.100.17"; - UDPSocket socket("abcdefghijklmnopqrst"); - EXPECT_NE(0, socket.SetMulticastTimeToLive(-1)); // Negative TTL shall fail. - EXPECT_EQ(0, socket.SetMulticastTimeToLive(3)); - socket.Connect(CreateAddressList(kGroup, 13333), base::Bind(&OnConnected)); + std::unique_ptr<UDPSocket> socket = CreateSocket(); + + EXPECT_NE(0, socket->SetMulticastTimeToLive(-1)); // Negative TTL shall fail. + EXPECT_EQ(0, socket->SetMulticastTimeToLive(3)); + socket->Connect(CreateAddressList(kGroup, 13333), + base::BindRepeating(&OnConnected)); } -TEST(UDPSocketUnitTest, TestUDPMulticastLoopbackMode) { +TEST_F(UDPSocketUnitTest, TestUDPMulticastLoopbackMode) { const char kGroup[] = "237.132.100.17"; - UDPSocket socket("abcdefghijklmnopqrst"); - EXPECT_EQ(0, socket.SetMulticastLoopbackMode(false)); - socket.Connect(CreateAddressList(kGroup, 13333), base::Bind(&OnConnected)); + std::unique_ptr<UDPSocket> socket = CreateSocket(); + + EXPECT_EQ(0, socket->SetMulticastLoopbackMode(false)); + socket->Connect(CreateAddressList(kGroup, 13333), + base::BindRepeating(&OnConnected)); } // Send a test multicast packet every second. @@ -102,8 +141,8 @@ UDPSocket* src, int result) { if (result == 0) { - scoped_refptr<net::IOBuffer> data = new net::WrappedIOBuffer(test_message); - src->Write(data, test_message_length, base::Bind(&OnSendCompleted)); + scoped_refptr<net::IOBuffer> data = new net::WrappedIOBuffer(kTestMessage); + src->Write(data, kTestMessageLength, base::BindRepeating(&OnSendCompleted)); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&SendMulticastPacket, quit_run_loop, src, result), @@ -118,37 +157,48 @@ bool* packet_received, int count, scoped_refptr<net::IOBuffer> io_buffer, - bool socket_destroying) { - EXPECT_EQ(test_message_length, count); - EXPECT_EQ(0, strncmp(io_buffer->data(), test_message, test_message_length)); + bool socket_destroying, + const std::string& ip, + uint16_t port) { + EXPECT_EQ(kTestMessageLength, count); + EXPECT_EQ(0, strncmp(io_buffer->data(), kTestMessage, kTestMessageLength)); *packet_received = true; quit_run_loop.Run(); } -TEST(UDPSocketUnitTest, TestUDPMulticastRecv) { +TEST_F(UDPSocketUnitTest, TestUDPMulticastRecv) { const int kPort = 9999; const char kGroup[] = "237.132.100.17"; bool packet_received = false; - base::MessageLoopForIO io_loop; // For Read to do its threaded work. - UDPSocket dest("abcdefghijklmnopqrst"); - UDPSocket src("abcdefghijklmnopqrst"); - - base::RunLoop run_loop; + std::unique_ptr<UDPSocket> src = CreateSocket(); + std::unique_ptr<UDPSocket> dest = CreateSocket(); // Receiver - EXPECT_EQ(0, dest.Bind("0.0.0.0", kPort)); - EXPECT_EQ(0, dest.JoinGroup(kGroup)); - dest.Read(1024, base::Bind(&OnMulticastReadCompleted, run_loop.QuitClosure(), - &packet_received)); + { + net::TestCompletionCallback callback; + dest->Bind("0.0.0.0", kPort, callback.callback()); + EXPECT_EQ(net::OK, callback.WaitForResult()); + } + { + net::TestCompletionCallback callback; + dest->JoinGroup(kGroup, callback.callback()); + EXPECT_EQ(net::OK, callback.WaitForResult()); + } + base::RunLoop run_loop; + // |dest| is used with Bind(), so use RecvFrom() instead of Read(). + dest->RecvFrom(1024, + base::BindRepeating(&OnMulticastReadCompleted, + run_loop.QuitClosure(), &packet_received)); // Sender - EXPECT_EQ(0, src.SetMulticastTimeToLive(0)); - src.Connect(CreateAddressList(kGroup, kPort), - base::Bind(&SendMulticastPacket, run_loop.QuitClosure(), &src)); + EXPECT_EQ(0, src->SetMulticastTimeToLive(0)); + src->Connect(CreateAddressList(kGroup, kPort), + base::BindRepeating(&SendMulticastPacket, run_loop.QuitClosure(), + src.get())); // If not received within the test action timeout, quit the message loop. - io_loop.task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), - TestTimeouts::action_timeout()); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::action_timeout()); run_loop.Run();
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 39663e4..e445dbc 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -862,7 +862,8 @@ return RespondNow(Error(keys::kNoSelectedTabError)); return RespondNow(ArgumentList( tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject( - contents, tab_strip, tab_strip->active_index(), extension())))); + contents, ExtensionTabUtil::kScrubTab, extension(), tab_strip, + tab_strip->active_index())))); } ExtensionFunction::ResponseAction TabsGetAllInWindowFunction::Run() { @@ -1045,8 +1046,9 @@ if (loading_status_set && loading != web_contents->IsLoading()) continue; - result->Append(ExtensionTabUtil::CreateTabObject(web_contents, tab_strip, - i, extension()) + result->Append(ExtensionTabUtil::CreateTabObject( + web_contents, ExtensionTabUtil::kScrubTab, extension(), + tab_strip, i) ->ToValue()); } } @@ -1113,7 +1115,8 @@ return RespondNow(ArgumentList( tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject( - new_contents, new_tab_strip, new_tab_index, extension())))); + new_contents, ExtensionTabUtil::kScrubTab, extension(), new_tab_strip, + new_tab_index)))); } ExtensionFunction::ResponseAction TabsGetFunction::Run() { @@ -1130,9 +1133,9 @@ return RespondNow(Error(error)); } - return RespondNow(ArgumentList( - tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject( - contents, tab_strip, tab_index, extension())))); + return RespondNow(ArgumentList(tabs::Get::Results::Create( + *ExtensionTabUtil::CreateTabObject(contents, ExtensionTabUtil::kScrubTab, + extension(), tab_strip, tab_index)))); } ExtensionFunction::ResponseAction TabsGetCurrentFunction::Run() { @@ -1143,8 +1146,8 @@ WebContents* caller_contents = GetSenderWebContents(); std::unique_ptr<base::ListValue> results; if (caller_contents && ExtensionTabUtil::GetTabId(caller_contents) >= 0) { - results = tabs::Get::Results::Create( - *ExtensionTabUtil::CreateTabObject(caller_contents, extension())); + results = tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject( + caller_contents, ExtensionTabUtil::kScrubTab, extension())); } return RespondNow(results ? ArgumentList(std::move(results)) : NoArguments()); } @@ -1434,8 +1437,8 @@ if (!has_callback()) return; - results_ = tabs::Get::Results::Create( - *ExtensionTabUtil::CreateTabObject(web_contents_, extension())); + results_ = tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject( + web_contents_, ExtensionTabUtil::kScrubTab, extension())); } void TabsUpdateFunction::OnExecuteCodeFinished( @@ -1563,10 +1566,10 @@ *new_index, web_contents, TabStripModel::ADD_NONE); if (has_callback()) { - tab_values->Append( - ExtensionTabUtil::CreateTabObject(web_contents, target_tab_strip, - *new_index, extension()) - ->ToValue()); + tab_values->Append(ExtensionTabUtil::CreateTabObject( + web_contents, ExtensionTabUtil::kScrubTab, + extension(), target_tab_strip, *new_index) + ->ToValue()); } return true; @@ -1585,7 +1588,8 @@ if (has_callback()) { tab_values->Append(ExtensionTabUtil::CreateTabObject( - contents, source_tab_strip, *new_index, extension()) + contents, ExtensionTabUtil::kScrubTab, extension(), + source_tab_strip, *new_index) ->ToValue()); } @@ -2188,8 +2192,9 @@ // Create the Tab object and return it in case of success. if (contents) { - return RespondNow(ArgumentList(tabs::Discard::Results::Create( - *ExtensionTabUtil::CreateTabObject(contents)))); + return RespondNow(ArgumentList( + tabs::Discard::Results::Create(*ExtensionTabUtil::CreateTabObject( + contents, ExtensionTabUtil::kScrubTab, extension())))); } // Return appropriate error message otherwise.
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc index 1ab063b..af63faf 100644 --- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc +++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -45,7 +45,8 @@ Event* event, const base::DictionaryValue* listener_filter) { std::unique_ptr<api::tabs::Tab> tab_object = - ExtensionTabUtil::CreateTabObject(contents, extension); + ExtensionTabUtil::CreateTabObject(contents, ExtensionTabUtil::kScrubTab, + extension); std::unique_ptr<base::DictionaryValue> tab_value = tab_object->ToValue(); @@ -190,7 +191,9 @@ const base::DictionaryValue* listener_filter) { event->event_args->Clear(); std::unique_ptr<base::DictionaryValue> tab_value = - ExtensionTabUtil::CreateTabObject(contents, extension)->ToValue(); + ExtensionTabUtil::CreateTabObject(contents, ExtensionTabUtil::kScrubTab, + extension) + ->ToValue(); tab_value->SetBoolean(tabs_constants::kSelectedKey, active); tab_value->SetBoolean(tabs_constants::kActiveKey, active); event->event_args->Append(std::move(tab_value));
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index d76a315..8a498e2f 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -1357,7 +1357,9 @@ // Creates Tab object to ensure the property is correct for the extension. std::unique_ptr<api::tabs::Tab> tab_object_a = - ExtensionTabUtil::CreateTabObject(web_contents_a, tab_strip_model, 0); + ExtensionTabUtil::CreateTabObject(web_contents_a, + ExtensionTabUtil::kDontScrubTab, + nullptr, tab_strip_model, 0); EXPECT_FALSE(tab_object_a->discarded); // Discards one tab. @@ -1365,8 +1367,9 @@ web_contents_a = tab_strip_model->GetWebContentsAt(1); // Make sure the property is changed accordingly after discarding the tab. - tab_object_a = - ExtensionTabUtil::CreateTabObject(web_contents_a, tab_strip_model, 0); + tab_object_a = ExtensionTabUtil::CreateTabObject( + web_contents_a, ExtensionTabUtil::kDontScrubTab, nullptr, tab_strip_model, + 0); EXPECT_TRUE(tab_object_a->discarded); // Get non-discarded tabs after discarding one tab. @@ -1471,6 +1474,8 @@ tab_id = ExtensionTabUtil::GetTabId(web_contents); EXPECT_EQ(tab_id, api_test_utils::GetInteger(result.get(), "id")); EXPECT_TRUE(api_test_utils::GetBoolean(result.get(), "discarded")); + // The result should be scrubbed. + EXPECT_FALSE(result->FindKey("url")); // Tests chrome.tabs.discard(tabId) with an already discarded tab. It has to // return the error stating that the tab couldn't be discarded. @@ -1543,6 +1548,8 @@ EXPECT_EQ(ExtensionTabUtil::GetTabId(web_contents), api_test_utils::GetInteger(result.get(), "id")); EXPECT_TRUE(api_test_utils::GetBoolean(result.get(), "discarded")); + // The result should be scrubbed. + EXPECT_FALSE(result->FindKey("url")); } // Tests chrome.tabs.discard() without disabling protection time. @@ -1584,7 +1591,9 @@ // Creates Tab object to ensure the property is correct for the extension. TabStripModel* tab_strip_model = browser()->tab_strip_model(); std::unique_ptr<api::tabs::Tab> tab_object_a = - ExtensionTabUtil::CreateTabObject(web_contents_a, tab_strip_model, 0); + ExtensionTabUtil::CreateTabObject(web_contents_a, + ExtensionTabUtil::kDontScrubTab, + nullptr, tab_strip_model, 0); EXPECT_TRUE(tab_object_a->auto_discardable); // Set up query and update functions with the extension. @@ -1626,8 +1635,9 @@ api_test_utils::GetBoolean(update_result.get(), "autoDiscardable")); // Make sure the property is changed accordingly after updating the tab. - tab_object_a = - ExtensionTabUtil::CreateTabObject(web_contents_a, tab_strip_model, 0); + tab_object_a = ExtensionTabUtil::CreateTabObject( + web_contents_a, ExtensionTabUtil::kDontScrubTab, nullptr, tab_strip_model, + 0); EXPECT_FALSE(tab_object_a->auto_discardable); // Get auto-discardable tabs after changing the status of web contents A.
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index 43b2715..26486ea 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -265,8 +265,8 @@ // Return data about the newly created tab. return ExtensionTabUtil::CreateTabObject(navigate_params.target_contents, - tab_strip, new_index, - function->extension()) + kScrubTab, function->extension(), + tab_strip, new_index) ->ToValue() .release(); } @@ -334,32 +334,8 @@ // static std::unique_ptr<api::tabs::Tab> ExtensionTabUtil::CreateTabObject( WebContents* contents, - TabStripModel* tab_strip, - int tab_index, - const Extension* extension) { - std::unique_ptr<api::tabs::Tab> result = - CreateTabObject(contents, tab_strip, tab_index); - ScrubTabForExtension(extension, contents, result.get()); - return result; -} - -std::unique_ptr<base::ListValue> ExtensionTabUtil::CreateTabList( - const Browser* browser, - const Extension* extension) { - std::unique_ptr<base::ListValue> tab_list(new base::ListValue()); - TabStripModel* tab_strip = browser->tab_strip_model(); - for (int i = 0; i < tab_strip->count(); ++i) { - tab_list->Append( - CreateTabObject(tab_strip->GetWebContentsAt(i), tab_strip, i, extension) - ->ToValue()); - } - - return tab_list; -} - -// static -std::unique_ptr<api::tabs::Tab> ExtensionTabUtil::CreateTabObject( - content::WebContents* contents, + ScrubTabBehavior scrub_tab_behavior, + const Extension* extension, TabStripModel* tab_strip, int tab_index) { if (!tab_strip) @@ -402,9 +378,25 @@ } } + if (scrub_tab_behavior == kScrubTab) + ScrubTabForExtension(extension, contents, tab_object.get()); return tab_object; } +std::unique_ptr<base::ListValue> ExtensionTabUtil::CreateTabList( + const Browser* browser, + const Extension* extension) { + std::unique_ptr<base::ListValue> tab_list(new base::ListValue()); + TabStripModel* tab_strip = browser->tab_strip_model(); + for (int i = 0; i < tab_strip->count(); ++i) { + tab_list->Append(CreateTabObject(tab_strip->GetWebContentsAt(i), kScrubTab, + extension, tab_strip, i) + ->ToValue()); + } + + return tab_list; +} + // static std::unique_ptr<base::DictionaryValue> ExtensionTabUtil::CreateWindowValueForExtension(
diff --git a/chrome/browser/extensions/extension_tab_util.h b/chrome/browser/extensions/extension_tab_util.h index 64a4693e..a813302 100644 --- a/chrome/browser/extensions/extension_tab_util.h +++ b/chrome/browser/extensions/extension_tab_util.h
@@ -44,6 +44,11 @@ kDontPopulateTabs, }; + enum ScrubTabBehavior { + kScrubTab, + kDontScrubTab, + }; + struct OpenTabParams { OpenTabParams(); ~OpenTabParams(); @@ -93,31 +98,23 @@ static std::string GetBrowserWindowTypeText(const Browser& browser); // Creates a Tab object (see chrome/common/extensions/api/tabs.json) with - // information about the state of a browser tab. Depending on the - // permissions of the extension, the object may or may not include sensitive - // data such as the tab's URL. + // information about the state of a browser tab for the given |web_contents|. + // This will scrub the tab of sensitive data (URL, favicon, title) according + // to |scrub_tab_behavior| and |extension|'s permissions. A null extension is + // treated as having no permissions. + // By default, tab information should always be scrubbed (kScrubTab) for any + // data passed to any extension. static std::unique_ptr<api::tabs::Tab> CreateTabObject( content::WebContents* web_contents, + ScrubTabBehavior scrub_tab_behavior, const Extension* extension) { - return CreateTabObject(web_contents, nullptr, -1, extension); + return CreateTabObject(web_contents, scrub_tab_behavior, extension, nullptr, + -1); } static std::unique_ptr<api::tabs::Tab> CreateTabObject( content::WebContents* web_contents, - TabStripModel* tab_strip, - int tab_index, - const Extension* extension); - - // Creates a Tab object but performs no extension permissions checks; the - // returned object will contain privacy-sensitive data. - // TODO(devlin): These are easy to confuse with the safer, info-scrubbing - // versions above. We should get rid of these, and have callers explicitly - // pass in a null extension if they do not want values scrubbed. - static std::unique_ptr<api::tabs::Tab> CreateTabObject( - content::WebContents* web_contents) { - return CreateTabObject(web_contents, nullptr, -1); - } - static std::unique_ptr<api::tabs::Tab> CreateTabObject( - content::WebContents* web_contents, + ScrubTabBehavior scrub_tab_behavior, + const Extension* extension, TabStripModel* tab_strip, int tab_index);
diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc index 86dd4a5..fa08eac9 100644 --- a/chrome/browser/extensions/menu_manager.cc +++ b/chrome/browser/extensions/menu_manager.cc
@@ -691,7 +691,13 @@ if (frame_id != ExtensionApiFrameIdMap::kInvalidFrameId) raw_properties->SetInteger("frameId", frame_id); - args->Append(ExtensionTabUtil::CreateTabObject(web_contents)->ToValue()); + // We intentionally don't scrub the tab data here, since the user chose to + // invoke the extension on the page. + // NOTE(devlin): We could potentially gate this on whether the extension + // has activeTab. + args->Append(ExtensionTabUtil::CreateTabObject( + web_contents, ExtensionTabUtil::kDontScrubTab, extension) + ->ToValue()); } else { args->Append(std::make_unique<base::DictionaryValue>()); }
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index 1e789b3..bf70f0c 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc
@@ -196,7 +196,7 @@ return; // Start fetching web app info for CreateApplicationShortcut dialog and show - // the dialog when the data is available in OnDidGetApplicationInfo. + // the dialog when the data is available in OnDidGetWebApplicationInfo. GetApplicationInfo(CREATE_HOSTED_APP); }
diff --git a/chrome/browser/extensions/tab_helper.h b/chrome/browser/extensions/tab_helper.h index ba49aea..ede3883 100644 --- a/chrome/browser/extensions/tab_helper.h +++ b/chrome/browser/extensions/tab_helper.h
@@ -114,7 +114,7 @@ void InvokeForContentRulesRegistries(const Func& func); // Different types of action when web app info is available. - // OnDidGetApplicationInfo uses this to dispatch calls. + // OnDidGetWebApplicationInfo uses this to dispatch calls. enum WebAppAction { NONE, // No action at all. CREATE_HOSTED_APP, // Create and install a hosted app. @@ -188,7 +188,7 @@ ExtensionReenabler::ReenableResult result); // Requests application info for the specified page. This is an asynchronous - // request. The delegate is notified by way of OnDidGetApplicationInfo when + // request. The delegate is notified by way of OnDidGetWebApplicationInfo when // the data is available. void GetApplicationInfo(WebAppAction action); @@ -212,8 +212,8 @@ // Cached web app info data. WebApplicationInfo web_app_info_; - // Which deferred action to perform when OnDidGetApplicationInfo is notified - // from a WebContents. + // Which deferred action to perform when OnDidGetWebApplicationInfo is + // notified from a WebContents. WebAppAction pending_web_app_action_; // Which navigation entry was active when the GetApplicationInfo request was
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 89ec796c..b98178c 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -545,9 +545,9 @@ const char kOOPHPStackModeNativeWithThreadNames[] = "Native with thread names"; const char kOOPHPStackModePseudo[] = "Trace events"; -const char kEnablePictureInPictureName[] = "Enable picture in picture."; +const char kEnablePictureInPictureName[] = "Enable Picture-in-Picture."; const char kEnablePictureInPictureDescription[] = - "Enable the picture in picture feature for videos."; + "Enable the Picture-in-Picture feature for videos."; const char kEnablePixelCanvasRecordingName[] = "Enable pixel canvas recording"; const char kEnablePixelCanvasRecordingDescription[] =
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc index 3e90b659..aa23045a 100644 --- a/chrome/browser/lifetime/application_lifetime.cc +++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -27,7 +27,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/user_manager.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/features.h" #include "chrome/common/pref_names.h" @@ -56,6 +55,10 @@ #include "third_party/cros_system_api/dbus/service_constants.h" #endif +#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) +#include "chrome/browser/ui/user_manager.h" +#endif + #if defined(OS_WIN) #include "base/win/win_util.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
diff --git a/chrome/browser/notifications/notification_permission_context_unittest.cc b/chrome/browser/notifications/notification_permission_context_unittest.cc index 2cd0621..ba41a5e 100644 --- a/chrome/browser/notifications/notification_permission_context_unittest.cc +++ b/chrome/browser/notifications/notification_permission_context_unittest.cc
@@ -11,6 +11,7 @@ #include "base/memory/ptr_util.h" #include "base/test/scoped_mock_time_message_loop_task_runner.h" #include "base/time/time.h" +#include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/notifications/desktop_notification_profile_util.h" #include "chrome/browser/permissions/permission_manager.h" @@ -29,6 +30,10 @@ #include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h" #include "url/gurl.h" +#if defined(OS_ANDROID) +#include "base/android/build_info.h" +#endif // defined(OS_ANDROID) + namespace { void DoNothing(ContentSetting content_setting) {} @@ -152,6 +157,21 @@ requesting_origin, embedding_origin) .content_setting); +// Now block permission for |requesting_origin|. + +#if defined(OS_ANDROID) + // On Android O+, permission must be reset before it can be blocked. This is + // because granting a permission on O+ creates a system-managed notification + // channel which determines the value of the content setting, so it is not + // allowed to then toggle the value from ALLOW->BLOCK directly. However, + // Chrome may reset the permission (which deletes the channel), and *then* + // grant/block it (creating a new channel). + if (base::android::BuildInfo::GetInstance()->sdk_int() >= + base::android::SDK_VERSION_OREO) { + context.ResetPermission(requesting_origin, requesting_origin); + } +#endif // defined(OS_ANDROID) + UpdateContentSetting(&context, requesting_origin, requesting_origin, CONTENT_SETTING_BLOCK);
diff --git a/chrome/browser/offline_pages/offline_page_request_job_unittest.cc b/chrome/browser/offline_pages/offline_page_request_job_unittest.cc index 465bbbf..feca01f8 100644 --- a/chrome/browser/offline_pages/offline_page_request_job_unittest.cc +++ b/chrome/browser/offline_pages/offline_page_request_job_unittest.cc
@@ -293,35 +293,6 @@ DISALLOW_COPY_AND_ASSIGN(TestOfflinePageArchiver); }; -std::unique_ptr<KeyedService> BuildTestOfflinePageModel( - content::BrowserContext* context) { - scoped_refptr<base::SingleThreadTaskRunner> task_runner = - base::ThreadTaskRunnerHandle::Get(); - - base::FilePath store_path = - context->GetPath().Append(chrome::kOfflinePageMetadataDirname); - std::unique_ptr<OfflinePageMetadataStoreSQL> metadata_store( - new OfflinePageMetadataStoreSQL(task_runner, store_path)); - - base::FilePath test_data_dir_path; - PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_path); - base::FilePath private_archives_dir = - test_data_dir_path.AppendASCII(kPrivateOfflineFileDir); - base::FilePath public_archives_dir = - test_data_dir_path.AppendASCII(kPublicOfflineFileDir); - - // Since we're not saving page into temporary dir, it's set the same as the - // private dir. - std::unique_ptr<ArchiveManager> archive_manager( - new ArchiveManager(private_archives_dir, private_archives_dir, - public_archives_dir, task_runner)); - std::unique_ptr<base::Clock> clock(new base::DefaultClock); - - return std::unique_ptr<KeyedService>(new OfflinePageModelTaskified( - std::move(metadata_store), std::move(archive_manager), task_runner, - std::move(clock))); -} - // Helper function to make a character array filled with |size| bytes of // test content. std::string MakeContentOfSize(int size) { @@ -341,6 +312,7 @@ ~OfflinePageRequestJobTest() override {} void SetUp() override; + void TearDown() override; void SimulateHasNetworkConnectivity(bool has_connectivity); void RunUntilIdle(); @@ -449,6 +421,15 @@ } private: + static std::unique_ptr<KeyedService> BuildTestOfflinePageModel( + content::BrowserContext* context); + + // TODO(https://crbug.com/809610): The static members below will be removed + // once the reference to BuildTestOfflinePageModel in SetUp is converted to a + // base::OnceCallback. + static base::FilePath private_archives_dir_; + static base::FilePath public_archives_dir_; + void OnSavePageDone(SavePageResult result, int64_t offline_id); std::unique_ptr<net::URLRequest> CreateRequest( const GURL& url, @@ -496,6 +477,8 @@ intercepting_job_factory_; std::unique_ptr<TestURLRequestDelegate> url_request_delegate_; std::unique_ptr<net::URLRequest> request_; + base::ScopedTempDir private_archives_temp_base_dir_; + base::ScopedTempDir public_archives_temp_base_dir_; base::ScopedTempDir temp_dir_; base::FilePath temp_file_path_; @@ -526,9 +509,23 @@ OfflinePageTabHelper::FromWebContents(web_contents_.get()); // Set up the factory for testing. + // Note: The extra dir into the temp folder is needed so that the helper + // dir-copy operation works properly. That operation copies the source dir + // final path segment into the destination, and not only its immediate + // contents so this same-named path here makes the archive dir variable point + // to the correct location. + // TODO(romax): add the more recent "temporary" dir here instead of reusing + // the private one. + ASSERT_TRUE(private_archives_temp_base_dir_.CreateUniqueTempDir()); + private_archives_dir_ = private_archives_temp_base_dir_.GetPath().AppendASCII( + kPrivateOfflineFileDir); + ASSERT_TRUE(public_archives_temp_base_dir_.CreateUniqueTempDir()); + public_archives_dir_ = public_archives_temp_base_dir_.GetPath().AppendASCII( + kPublicOfflineFileDir); OfflinePageModelFactory::GetInstance()->SetTestingFactoryAndUse( - profile(), BuildTestOfflinePageModel); + profile(), &OfflinePageRequestJobTest::BuildTestOfflinePageModel); + // Initialize OfflinePageModel. OfflinePageModelTaskified* model = static_cast<OfflinePageModelTaskified*>( OfflinePageModelFactory::GetForBrowserContext(profile())); @@ -538,8 +535,28 @@ // metadata already written to the store. model->SetSkipClearingOriginalUrlForTesting(); - // Initialize OfflinePageModel. - RunUntilIdle(); + // Move test data files into their respective temporary test directories. The + // model's maintenance tasks must not be executed in the meantime otherwise + // these files will be wiped by consistency checks. + base::FilePath test_data_dir_path; + PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_path); + base::FilePath test_data_private_archives_dir = + test_data_dir_path.AppendASCII(kPrivateOfflineFileDir); + ASSERT_TRUE(base::CopyDirectory(test_data_private_archives_dir, + private_archives_dir_.DirName(), true)); + base::FilePath test_data_public_archives_dir = + test_data_dir_path.AppendASCII(kPublicOfflineFileDir); + ASSERT_TRUE(base::CopyDirectory(test_data_public_archives_dir, + public_archives_dir_.DirName(), true)); +} + +void OfflinePageRequestJobTest::TearDown() { + EXPECT_TRUE(private_archives_temp_base_dir_.Delete()); + EXPECT_TRUE(public_archives_temp_base_dir_.Delete()); + // This check confirms that the model's maintenance tasks were not executed + // during the test run. + histogram_tester_.ExpectTotalCount("OfflinePages.ClearTemporaryPages.Result", + 0); } void OfflinePageRequestJobTest::SimulateHasNetworkConnectivity(bool online) { @@ -806,10 +823,7 @@ if (file_path.IsAbsolute()) { final_path = file_path; } else { - base::FilePath test_data_dir_path; - PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_path); - final_path = - test_data_dir_path.AppendASCII(kPublicOfflineFileDir).Append(file_path); + final_path = public_archives_dir_.Append(file_path); } return SavePage(url, original_url, final_path, file_size, digest); @@ -825,10 +839,7 @@ if (file_path.IsAbsolute()) { final_path = file_path; } else { - base::FilePath test_data_dir_path; - PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_path); - final_path = test_data_dir_path.AppendASCII(kPrivateOfflineFileDir) - .Append(file_path); + final_path = private_archives_dir_.Append(file_path); } return SavePage(url, original_url, final_path, file_size, digest); @@ -861,6 +872,34 @@ return last_offline_id_; } +// static +std::unique_ptr<KeyedService> +OfflinePageRequestJobTest::BuildTestOfflinePageModel( + content::BrowserContext* context) { + scoped_refptr<base::SingleThreadTaskRunner> task_runner = + base::ThreadTaskRunnerHandle::Get(); + + base::FilePath store_path = + context->GetPath().Append(chrome::kOfflinePageMetadataDirname); + std::unique_ptr<OfflinePageMetadataStoreSQL> metadata_store( + new OfflinePageMetadataStoreSQL(task_runner, store_path)); + + // Since we're not saving page into temporary dir, it's set the same as the + // private dir. + std::unique_ptr<ArchiveManager> archive_manager( + new ArchiveManager(private_archives_dir_, private_archives_dir_, + public_archives_dir_, task_runner)); + std::unique_ptr<base::Clock> clock(new base::DefaultClock); + + return std::unique_ptr<KeyedService>(new OfflinePageModelTaskified( + std::move(metadata_store), std::move(archive_manager), task_runner, + std::move(clock))); +} + +// static +base::FilePath OfflinePageRequestJobTest::private_archives_dir_; +base::FilePath OfflinePageRequestJobTest::public_archives_dir_; + void OfflinePageRequestJobTest::OnSavePageDone(SavePageResult result, int64_t offline_id) { ASSERT_EQ(SavePageResult::SUCCESS, result);
diff --git a/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc index af63d41..3ddcc80 100644 --- a/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc
@@ -65,6 +65,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.ParseTiming.NavigationToParseStart", timing.parse_timing->parse_start.value()); @@ -120,6 +121,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.PaintTiming." "NavigationToFirstContentfulPaint", @@ -181,6 +183,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.Experimental.PaintTiming." "NavigationToFirstMeaningfulPaint", @@ -232,6 +235,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.DocumentTiming." "NavigationToDOMContentLoadedEventFired", @@ -278,6 +282,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.DocumentTiming." "NavigationToLoadEventFired",
diff --git a/chrome/browser/profiles/avatar_menu.cc b/chrome/browser/profiles/avatar_menu.cc index d90f5867..26a79dc 100644 --- a/chrome/browser/profiles/avatar_menu.cc +++ b/chrome/browser/profiles/avatar_menu.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" -#include "chrome/browser/ui/user_manager.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/features.h" #include "chrome/grit/generated_resources.h" @@ -36,6 +35,10 @@ #include "chrome/browser/supervised_user/supervised_user_service_factory.h" #endif +#if !defined(OS_CHROMEOS) +#include "chrome/browser/ui/user_manager.h" +#endif // !defined(OS_CHROMEOS) + using content::BrowserThread; AvatarMenu::AvatarMenu(ProfileAttributesStorage* profile_storage,
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc index 42cc4d6..8c226f6 100644 --- a/chrome/browser/profiles/profile_window.cc +++ b/chrome/browser/profiles/profile_window.cc
@@ -35,7 +35,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/profile_chooser_constants.h" -#include "chrome/browser/ui/user_manager.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -67,6 +66,10 @@ #include "chrome/browser/ui/startup/startup_browser_creator.h" #endif // !defined (OS_ANDROID) +#if !defined(OS_CHROMEOS) +#include "chrome/browser/ui/user_manager.h" +#endif // !defined(OS_CHROMEOS) + using base::UserMetricsAction; using content::BrowserThread; @@ -354,8 +357,10 @@ } void ProfileBrowserCloseSuccess(const base::FilePath& profile_path) { +#if !defined(OS_CHROMEOS) UserManager::Show(base::FilePath(), profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); +#endif // !defined(OS_CHROMEOS) } void CloseGuestProfileWindows() { @@ -384,8 +389,10 @@ #endif // BUILDFLAG(ENABLE_EXTENSIONS) chrome::HideTaskManager(); +#if !defined(OS_CHROMEOS) UserManager::Show(profile_path, profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); +#endif // !defined(OS_CHROMEOS) } void LockProfile(Profile* profile) {
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index b2050ea..9683ea5 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -1071,9 +1071,11 @@ gcm::GCMEncryptionProvider::EncryptionInfoCallback callback) { if (PushMessagingAppIdentifier::UseInstanceID(app_id)) { GetInstanceIDDriver()->GetInstanceID(app_id)->GetEncryptionInfo( - NormalizeSenderInfo(sender_id), callback); + NormalizeSenderInfo(sender_id), + base::AdaptCallbackForRepeating(std::move(callback))); } else { - GetGCMDriver()->GetEncryptionInfo(app_id, callback); + GetGCMDriver()->GetEncryptionInfo( + app_id, base::AdaptCallbackForRepeating(std::move(callback))); } }
diff --git a/chrome/browser/renderer_host/chrome_navigation_ui_data.cc b/chrome/browser/renderer_host/chrome_navigation_ui_data.cc index c908555..a894296 100644 --- a/chrome/browser/renderer_host/chrome_navigation_ui_data.cc +++ b/chrome/browser/renderer_host/chrome_navigation_ui_data.cc
@@ -4,24 +4,41 @@ #include "chrome/browser/renderer_host/chrome_navigation_ui_data.h" +#include <tuple> + #include "base/memory/ptr_util.h" #include "chrome/browser/prerender/prerender_contents.h" #include "chrome/browser/prerender/prerender_histograms.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "content/public/browser/navigation_handle.h" #include "extensions/features/features.h" +#include "ui/base/window_open_disposition.h" -ChromeNavigationUIData::ChromeNavigationUIData() {} - -ChromeNavigationUIData::ChromeNavigationUIData( - content::NavigationHandle* navigation_handle) { - auto* web_contents = navigation_handle->GetWebContents(); #if BUILDFLAG(ENABLE_EXTENSIONS) +namespace { +std::pair<int, int> GetTabIdAndWindowId(content::WebContents* web_contents) { SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(web_contents); - int tab_id = session_tab_helper ? session_tab_helper->session_id().id() : -1; - int window_id = - session_tab_helper ? session_tab_helper->window_id().id() : -1; + if (!session_tab_helper) + return std::make_pair(-1, -1); + + return std::make_pair(session_tab_helper->session_id().id(), + session_tab_helper->window_id().id()); +} +} // namespace +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +ChromeNavigationUIData::ChromeNavigationUIData() + : disposition_(WindowOpenDisposition::CURRENT_TAB) {} + +ChromeNavigationUIData::ChromeNavigationUIData( + content::NavigationHandle* navigation_handle) + : disposition_(WindowOpenDisposition::CURRENT_TAB) { + auto* web_contents = navigation_handle->GetWebContents(); +#if BUILDFLAG(ENABLE_EXTENSIONS) + int tab_id; + int window_id; + std::tie(tab_id, window_id) = GetTabIdAndWindowId(web_contents); extension_data_ = base::MakeUnique<extensions::ExtensionNavigationUIData>( navigation_handle, tab_id, window_id); #endif @@ -38,11 +55,34 @@ ChromeNavigationUIData::~ChromeNavigationUIData() {} +// static +std::unique_ptr<ChromeNavigationUIData> +ChromeNavigationUIData::CreateForMainFrameNavigation( + content::WebContents* web_contents, + WindowOpenDisposition disposition) { + auto navigation_ui_data = std::make_unique<ChromeNavigationUIData>(); + navigation_ui_data->disposition_ = disposition; + +#if BUILDFLAG(ENABLE_EXTENSIONS) + int tab_id; + int window_id; + std::tie(tab_id, window_id) = GetTabIdAndWindowId(web_contents); + + navigation_ui_data->extension_data_ = + extensions::ExtensionNavigationUIData::CreateForMainFrameNavigation( + web_contents, tab_id, window_id); +#endif + + return navigation_ui_data; +} + std::unique_ptr<content::NavigationUIData> ChromeNavigationUIData::Clone() const { std::unique_ptr<ChromeNavigationUIData> copy = base::MakeUnique<ChromeNavigationUIData>(); + copy->disposition_ = disposition_; + #if BUILDFLAG(ENABLE_EXTENSIONS) if (extension_data_) copy->SetExtensionNavigationUIData(extension_data_->DeepCopy());
diff --git a/chrome/browser/renderer_host/chrome_navigation_ui_data.h b/chrome/browser/renderer_host/chrome_navigation_ui_data.h index de1cf32..9de483f 100644 --- a/chrome/browser/renderer_host/chrome_navigation_ui_data.h +++ b/chrome/browser/renderer_host/chrome_navigation_ui_data.h
@@ -19,6 +19,8 @@ class NavigationHandle; } +enum class WindowOpenDisposition; + // PlzNavigate // Contains data that is passed from the UI thread to the IO thread at the // beginning of each navigation. The class is instantiated on the UI thread, @@ -30,6 +32,10 @@ explicit ChromeNavigationUIData(content::NavigationHandle* navigation_handle); ~ChromeNavigationUIData() override; + static std::unique_ptr<ChromeNavigationUIData> CreateForMainFrameNavigation( + content::WebContents* web_contents, + WindowOpenDisposition disposition); + // Creates a new ChromeNavigationUIData that is a deep copy of the original. // Any changes to the original after the clone is created will not be // reflected in the clone. All owned data members are deep copied. @@ -54,7 +60,7 @@ return offline_page_data_.get(); } #endif - + WindowOpenDisposition window_open_disposition() const { return disposition_; } prerender::PrerenderMode prerender_mode() const { return prerender_mode_; } const std::string& prerender_histogram_prefix() { return prerender_histogram_prefix_; @@ -72,6 +78,7 @@ offline_page_data_; #endif + WindowOpenDisposition disposition_; prerender::PrerenderMode prerender_mode_ = prerender::NO_PRERENDER; std::string prerender_histogram_prefix_;
diff --git a/chrome/browser/resources/chromeos/arc_support/playstore.js b/chrome/browser/resources/chromeos/arc_support/playstore.js index 081938c..8d52066 100644 --- a/chrome/browser/resources/chromeos/arc_support/playstore.js +++ b/chrome/browser/resources/chromeos/arc_support/playstore.js
@@ -64,6 +64,7 @@ function processLangZoneTerms(initialLoad, language, countryCode) { var langSegments = language.split('-'); if (initialLoad && navigateToLanguageAndCountryCode(language, countryCode)) { + document.body.hidden = false; return true; }
diff --git a/chrome/browser/resources/chromeos/bluetooth_pairing_dialog/BUILD.gn b/chrome/browser/resources/chromeos/bluetooth_pairing_dialog/BUILD.gn new file mode 100644 index 0000000..15d7eeb --- /dev/null +++ b/chrome/browser/resources/chromeos/bluetooth_pairing_dialog/BUILD.gn
@@ -0,0 +1,12 @@ +import("../../optimize_webui.gni") + +optimize_webui("build") { + host = "bluetooth_pairing_dialog" + html_in_files = [ "bluetooth_pairing_dialog.html" ] + html_out_files = [ "vulcanized.html" ] + + input = rebase_path(".", root_build_dir) + js_out_files = [ "crisper.js" ] + + deps = [] +}
diff --git a/chrome/browser/resources/chromeos/bluetooth_pairing_dialog.html b/chrome/browser/resources/chromeos/bluetooth_pairing_dialog/bluetooth_pairing_dialog.html similarity index 100% rename from chrome/browser/resources/chromeos/bluetooth_pairing_dialog.html rename to chrome/browser/resources/chromeos/bluetooth_pairing_dialog/bluetooth_pairing_dialog.html
diff --git a/chrome/browser/resources/chromeos/bluetooth_pairing_dialog.js b/chrome/browser/resources/chromeos/bluetooth_pairing_dialog/bluetooth_pairing_dialog.js similarity index 100% rename from chrome/browser/resources/chromeos/bluetooth_pairing_dialog.js rename to chrome/browser/resources/chromeos/bluetooth_pairing_dialog/bluetooth_pairing_dialog.js
diff --git a/chrome/browser/resources/chromeos/bluetooth_pairing_dialog/compiled_resources2.gyp b/chrome/browser/resources/chromeos/bluetooth_pairing_dialog/compiled_resources2.gyp new file mode 100644 index 0000000..8abdc2c --- /dev/null +++ b/chrome/browser/resources/chromeos/bluetooth_pairing_dialog/compiled_resources2.gyp
@@ -0,0 +1,19 @@ +# Copyright 2018 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. +{ + 'targets': [ + { + 'target_name': 'bluetooth_pairing_dialog', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + '<(EXTERNS_GYP):bluetooth', + '<(EXTERNS_GYP):bluetooth_private', + '<(INTERFACES_GYP):bluetooth_interface', + '<(INTERFACES_GYP):bluetooth_private_interface', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + ], +}
diff --git a/chrome/browser/resources/chromeos/compiled_resources2.gyp b/chrome/browser/resources/chromeos/compiled_resources2.gyp index 2aff6fe..38d2711 100644 --- a/chrome/browser/resources/chromeos/compiled_resources2.gyp +++ b/chrome/browser/resources/chromeos/compiled_resources2.gyp
@@ -4,44 +4,13 @@ { 'targets': [ { - 'target_name': 'bluetooth_pairing_dialog', + 'target_name': 'chromeos_resources', + 'type': 'none', 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - '<(EXTERNS_GYP):bluetooth', - '<(EXTERNS_GYP):bluetooth_private', - '<(INTERFACES_GYP):bluetooth_interface', - '<(INTERFACES_GYP):bluetooth_private_interface', + 'bluetooth_pairing_dialog/compiled_resources2.gyp:*', + 'internet_config_dialog/compiled_resources2.gyp:*', + 'internet_detail_dialog/compiled_resources2.gyp:*', ], - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], }, - { - 'target_name': 'internet_config_dialog', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_components/chromeos/network/compiled_resources2.gyp:network_config', - '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', - '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - '<(EXTERNS_GYP):chrome_send', - '<(EXTERNS_GYP):networking_private', - '<(INTERFACES_GYP):networking_private_interface', - ], - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'internet_detail_dialog', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', - '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - '<(EXTERNS_GYP):chrome_send', - '<(EXTERNS_GYP):networking_private', - '<(INTERFACES_GYP):networking_private_interface', - ], - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - ], + ] }
diff --git a/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn b/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn new file mode 100644 index 0000000..b6041a5 --- /dev/null +++ b/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn
@@ -0,0 +1,12 @@ +import("../../optimize_webui.gni") + +optimize_webui("build") { + host = "internet_config_dialog" + html_in_files = [ "internet_config_dialog.html" ] + html_out_files = [ "vulcanized.html" ] + + input = rebase_path(".", root_build_dir) + js_out_files = [ "crisper.js" ] + + deps = [] +}
diff --git a/chrome/browser/resources/chromeos/internet_config_dialog/compiled_resources2.gyp b/chrome/browser/resources/chromeos/internet_config_dialog/compiled_resources2.gyp new file mode 100644 index 0000000..a75a8e4 --- /dev/null +++ b/chrome/browser/resources/chromeos/internet_config_dialog/compiled_resources2.gyp
@@ -0,0 +1,22 @@ +# Copyright 2018 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. +{ + 'targets': [ + { + 'target_name': 'internet_config_dialog', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_components/chromeos/network/compiled_resources2.gyp:network_config', + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', + '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + '<(EXTERNS_GYP):chrome_send', + '<(EXTERNS_GYP):networking_private', + '<(INTERFACES_GYP):networking_private_interface', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + ], +}
diff --git a/chrome/browser/resources/chromeos/internet_config_dialog.html b/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.html similarity index 100% rename from chrome/browser/resources/chromeos/internet_config_dialog.html rename to chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.html
diff --git a/chrome/browser/resources/chromeos/internet_config_dialog.js b/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.js similarity index 84% rename from chrome/browser/resources/chromeos/internet_config_dialog.js rename to chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.js index 2e2eef4..c3f8a7a 100644 --- a/chrome/browser/resources/chromeos/internet_config_dialog.js +++ b/chrome/browser/resources/chromeos/internet_config_dialog/internet_config_dialog.js
@@ -63,16 +63,23 @@ /** @override */ attached: function() { var dialogArgs = chrome.getVariableValue('dialogArguments'); - assert(dialogArgs); - var args = JSON.parse(dialogArgs); - var type = /** @type {chrome.networkingPrivate.NetworkType} */ (args.type); - assert(type); - this.guid_ = args.guid || ''; + var type; + if (dialogArgs) { + var args = JSON.parse(dialogArgs); + type = args.type; + assert(type); + this.guid_ = args.guid || ''; + } else { + // For debugging + var params = new URLSearchParams(document.location.search.substring(1)); + type = params.get('type') || 'WiFi'; + this.guid_ = params.get('guid') || ''; + } this.networkProperties_ = { GUID: this.guid_, Name: '', - Type: type, + Type: /** @type {chrome.networkingPrivate.NetworkType} */ (type), }; this.$.networkConfig.init();
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn b/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn new file mode 100644 index 0000000..a97168c --- /dev/null +++ b/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
@@ -0,0 +1,12 @@ +import("../../optimize_webui.gni") + +optimize_webui("build") { + host = "internet_detail_dialog" + html_in_files = [ "internet_detail_dialog.html" ] + html_out_files = [ "vulcanized.html" ] + + input = rebase_path(".", root_build_dir) + js_out_files = [ "crisper.js" ] + + deps = [] +}
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/compiled_resources2.gyp b/chrome/browser/resources/chromeos/internet_detail_dialog/compiled_resources2.gyp new file mode 100644 index 0000000..8d58322 --- /dev/null +++ b/chrome/browser/resources/chromeos/internet_detail_dialog/compiled_resources2.gyp
@@ -0,0 +1,20 @@ +# Copyright 2018 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. +{ + 'targets': [ + { + 'target_name': 'internet_detail_dialog', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/cr_elements/chromeos/network/compiled_resources2.gyp:cr_onc_types', + '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_network_behavior', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + '<(EXTERNS_GYP):chrome_send', + '<(EXTERNS_GYP):networking_private', + '<(INTERFACES_GYP):networking_private_interface', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + ], +}
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog.html b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html similarity index 100% rename from chrome/browser/resources/chromeos/internet_detail_dialog.html rename to chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog.js b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js similarity index 98% rename from chrome/browser/resources/chromeos/internet_detail_dialog.js rename to chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js index f810020..a349435 100644 --- a/chrome/browser/resources/chromeos/internet_detail_dialog.js +++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
@@ -49,6 +49,11 @@ /** @override */ attached: function() { this.guid = chrome.getVariableValue('dialogArguments'); + // For debugging + if (!this.guid) { + var params = new URLSearchParams(document.location.search.substring(1)); + this.guid = params.get('guid') || ''; + } if (!this.guid) { console.error('Invalid guid'); this.close_();
diff --git a/chrome/browser/resources/md_bookmarks/list.html b/chrome/browser/resources/md_bookmarks/list.html index 19279163..ddbf28f 100644 --- a/chrome/browser/resources/md_bookmarks/list.html +++ b/chrome/browser/resources/md_bookmarks/list.html
@@ -21,7 +21,7 @@ } #list { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background-color: #fff; margin: 0 auto; max-width: var(--card-max-width);
diff --git a/chrome/browser/resources/md_downloads/item.html b/chrome/browser/resources/md_downloads/item.html index b29e35f9..6953019 100644 --- a/chrome/browser/resources/md_downloads/item.html +++ b/chrome/browser/resources/md_downloads/item.html
@@ -54,7 +54,7 @@ } #content.is-active { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; } #content:not(.is-active) {
diff --git a/chrome/browser/resources/md_downloads/manager.html b/chrome/browser/resources/md_downloads/manager.html index e106ac3..3662b4d 100644 --- a/chrome/browser/resources/md_downloads/manager.html +++ b/chrome/browser/resources/md_downloads/manager.html
@@ -40,7 +40,7 @@ } #drop-shadow { - @apply(--cr-container-shadow); + @apply --cr-container-shadow; } :host([has-shadow_]) #drop-shadow {
diff --git a/chrome/browser/resources/md_extensions/detail_view.html b/chrome/browser/resources/md_extensions/detail_view.html index a111266..72b05c4 100644 --- a/chrome/browser/resources/md_extensions/detail_view.html +++ b/chrome/browser/resources/md_extensions/detail_view.html
@@ -55,7 +55,7 @@ } #main { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background-color: white; margin: auto; min-height: 100%; @@ -80,7 +80,7 @@ #name { flex-grow: 1; - @apply(--cr-title-text); + @apply --cr-title-text; } #learn-more-link { @@ -93,7 +93,7 @@ } .section { - @apply(--cr-section); + @apply --cr-section; } .section.block { @@ -187,7 +187,7 @@ } paper-spinner-lite { - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; } </style> <div id="container">
diff --git a/chrome/browser/resources/md_extensions/error_page.html b/chrome/browser/resources/md_extensions/error_page.html index 2cae6446..673c8084 100644 --- a/chrome/browser/resources/md_extensions/error_page.html +++ b/chrome/browser/resources/md_extensions/error_page.html
@@ -31,7 +31,7 @@ iron-icon { --iron-icon-fill-color: var(--paper-grey-500); - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; flex-shrink: 0; } @@ -47,7 +47,7 @@ * detail_view.html and error_page.html. Refactor such that no duplication * happens.*/ #main { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background-color: white; margin: auto; min-height: 100%; @@ -64,7 +64,7 @@ height: 40px; margin-bottom: 30px; padding: 8px 12px 0; - @apply(--cr-title-text); + @apply --cr-title-text; } #heading span { @@ -77,7 +77,7 @@ } .error-item { - @apply(--cr-section); + @apply --cr-section; padding-left: 0; } @@ -108,7 +108,7 @@ } .details-heading { - @apply(--cr-title-text); + @apply --cr-title-text; align-items: center; display: flex; height: var(--cr-section-min-height);
diff --git a/chrome/browser/resources/md_extensions/item.html b/chrome/browser/resources/md_extensions/item.html index f9f2d77..286119ec 100644 --- a/chrome/browser/resources/md_extensions/item.html +++ b/chrome/browser/resources/md_extensions/item.html
@@ -60,7 +60,7 @@ } #card { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background: white; border-radius: 2px; display: flex; @@ -90,7 +90,7 @@ } #name-and-version { - @apply(--cr-primary-text); + @apply --cr-primary-text; margin-bottom: 4px; } @@ -177,7 +177,7 @@ paper-tooltip { --paper-tooltip: { - @apply(--cr-tooltip); + @apply --cr-tooltip; min-width: 0; }; } @@ -342,7 +342,7 @@ $i18n{itemReload} </paper-button> </template> - <cr-toggle id="enable-toggle" class="action-button" + <cr-toggle id="enable-toggle" aria-label$="[[appOrExtension( data.type, '$i18nPolymer{appEnabled}',
diff --git a/chrome/browser/resources/md_extensions/item_list.html b/chrome/browser/resources/md_extensions/item_list.html index 2ac11ba..f4cb5c6f 100644 --- a/chrome/browser/resources/md_extensions/item_list.html +++ b/chrome/browser/resources/md_extensions/item_list.html
@@ -49,7 +49,7 @@ } #app-title { - @apply(--cr-section-text); + @apply --cr-section-text; margin-bottom: 12px; margin-top: 21px; }
diff --git a/chrome/browser/resources/md_history/app.html b/chrome/browser/resources/md_history/app.html index 5afaa5d..a6bfb16 100644 --- a/chrome/browser/resources/md_history/app.html +++ b/chrome/browser/resources/md_history/app.html
@@ -49,7 +49,7 @@ } #drop-shadow { - @apply(--cr-container-shadow); + @apply --cr-container-shadow; } :host([toolbar-shadow_]) #drop-shadow {
diff --git a/chrome/browser/resources/md_history/history_item.html b/chrome/browser/resources/md_history/history_item.html index 958032b..221f09b 100644 --- a/chrome/browser/resources/md_history/history_item.html +++ b/chrome/browser/resources/md_history/history_item.html
@@ -169,7 +169,7 @@ } #background { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background: #fff; bottom: 0; left: 0;
diff --git a/chrome/browser/resources/md_history/history_list.html b/chrome/browser/resources/md_history/history_list.html index a7a91c7..81b7d12 100644 --- a/chrome/browser/resources/md_history/history_list.html +++ b/chrome/browser/resources/md_history/history_list.html
@@ -23,7 +23,7 @@ } iron-list { - @apply(--card-sizing); + @apply --card-sizing; margin-top: var(--first-card-padding-top); }
diff --git a/chrome/browser/resources/md_history/synced_device_card.html b/chrome/browser/resources/md_history/synced_device_card.html index 708f60b..a9cc415 100644 --- a/chrome/browser/resources/md_history/synced_device_card.html +++ b/chrome/browser/resources/md_history/synced_device_card.html
@@ -16,7 +16,7 @@ <template> <style include="shared-style"> :host { - @apply(--card-sizing); + @apply --card-sizing; -webkit-tap-highlight-color: transparent; display: block; padding-bottom: var(--card-padding-between); @@ -57,7 +57,7 @@ } #history-item-container { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background: #fff; border-radius: 2px; }
diff --git a/chrome/browser/resources/md_user_manager/shared_styles.html b/chrome/browser/resources/md_user_manager/shared_styles.html index 7c9d1aa1..02eac8f 100644 --- a/chrome/browser/resources/md_user_manager/shared_styles.html +++ b/chrome/browser/resources/md_user_manager/shared_styles.html
@@ -26,7 +26,7 @@ } paper-button.action { - @apply(--action-button); + @apply --action-button; } paper-button.action.primary {
diff --git a/chrome/browser/resources/md_user_manager/user_manager.html b/chrome/browser/resources/md_user_manager/user_manager.html index 8dbe1d9..244e1595 100644 --- a/chrome/browser/resources/md_user_manager/user_manager.html +++ b/chrome/browser/resources/md_user_manager/user_manager.html
@@ -322,7 +322,7 @@ --paper-button-flat-keyboard-focus: { background: rgb(173, 50, 36); }; - @apply(--action-button); + @apply --action-button; } #user-manager-prompt-message {
diff --git a/chrome/browser/resources/media_router/elements/route_details/route_details.css b/chrome/browser/resources/media_router/elements/route_details/route_details.css index 92f8b1a..e5b7f3e 100644 --- a/chrome/browser/resources/media_router/elements/route_details/route_details.css +++ b/chrome/browser/resources/media_router/elements/route_details/route_details.css
@@ -3,8 +3,8 @@ * found in the LICENSE file. */ #route-action-buttons { - @apply(--layout-horizontal); - @apply(--layout-end-justified); + @apply --layout-horizontal; + @apply --layout-end-justified; margin: 0 10px; padding: 0; white-space: nowrap;
diff --git a/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html b/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html index 7320212..174b498 100644 --- a/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html +++ b/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html
@@ -8,8 +8,8 @@ <template> <style> #item { - @apply(--layout-center); - @apply(--layout-horizontal); + @apply --layout-center; + @apply --layout-horizontal; cursor: pointer; height: 30px; position: relative;
diff --git a/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html b/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html index 1d5c1ad9..af50fd9 100644 --- a/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html +++ b/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
@@ -28,7 +28,7 @@ } #title { - @apply(--layout-flex-5); + @apply --layout-flex-5; font-size: 0.87rem; font-weight: 500; overflow: hidden; @@ -37,7 +37,7 @@ } #pageselector-container { - @apply(--layout-flex-1); + @apply --layout-flex-1; text-align: center; /* The container resizes according to the width of the toolbar. On small * screens with large numbers of pages, overflow page numbers without @@ -46,7 +46,7 @@ } #buttons { - @apply(--layout-flex-5); + @apply --layout-flex-5; text-align: end; user-select: none; } @@ -68,7 +68,7 @@ } #toolbar { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background-color: rgb(50, 54, 57); color: rgb(241, 241, 241); display: flex;
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html index 2e3e618..95d7588 100644 --- a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html +++ b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
@@ -26,7 +26,7 @@ } #dropdown { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background-color: rgb(256, 256, 256); border-radius: 4px; color: var(--primary-text-color);
diff --git a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html index 83d3d8d..28ed7680 100644 --- a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html +++ b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html
@@ -21,7 +21,7 @@ } paper-fab { - @apply(--shadow-elevation-4dp); + @apply --shadow-elevation-4dp; --paper-fab-keyboard-focus-background: var(--viewer-icon-ink-color); --paper-fab-mini: { height: 36px;
diff --git a/chrome/browser/resources/pdf/open_pdf_params_parser.js b/chrome/browser/resources/pdf/open_pdf_params_parser.js index e573656..5903e40 100644 --- a/chrome/browser/resources/pdf/open_pdf_params_parser.js +++ b/chrome/browser/resources/pdf/open_pdf_params_parser.js
@@ -2,25 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var OpenPDFParamsParser; - (function() { 'use strict'; /** - * Creates a new OpenPDFParamsParser. This parses the open pdf parameters - * passed in the url to set initial viewport settings for opening the pdf. - * @param {!Function} getNamedDestinationsFunction The function called to fetch - * the page number for a named destination. - * @constructor + * Parses the open pdf parameters passed in the url to set initial viewport + * settings for opening the pdf. */ -OpenPDFParamsParser = function(getNamedDestinationsFunction) { - this.outstandingRequests_ = []; - this.getNamedDestinationsFunction_ = getNamedDestinationsFunction; -}; +window.OpenPDFParamsParser = class { + /** + * Constructor. + * @param {function(Object)} postMessageCallback + * Function called to fetch information for a named destination. + */ + constructor(postMessageCallback) { + /** @private {!Array<!Object>} */ + this.outstandingRequests_ = []; -OpenPDFParamsParser.prototype = { + /** @private {!function(Object)} */ + this.postMessageCallback_ = postMessageCallback; + } + /** * @private * Parse zoom parameter of open PDF parameters. The PDF should be opened at @@ -28,14 +31,14 @@ * @param {string} paramValue zoom value. * @return {Object} Map with zoom parameters (zoom and position). */ - parseZoomParam_: function(paramValue) { - var paramValueSplit = paramValue.split(','); + parseZoomParam_(paramValue) { + const paramValueSplit = paramValue.split(','); if (paramValueSplit.length != 1 && paramValueSplit.length != 3) return {}; // User scale of 100 means zoom value of 100% i.e. zoom factor of 1.0. - var zoomFactor = parseFloat(paramValueSplit[0]) / 100; - if (isNaN(zoomFactor)) + const zoomFactor = parseFloat(paramValueSplit[0]) / 100; + if (Number.isNaN(zoomFactor)) return {}; // Handle #zoom=scale. @@ -44,12 +47,12 @@ } // Handle #zoom=scale,left,top. - var position = { + const position = { x: parseFloat(paramValueSplit[1]), y: parseFloat(paramValueSplit[2]) }; return {'position': position, 'zoom': zoomFactor}; - }, + } /** * @private @@ -58,14 +61,14 @@ * @param {string} paramValue view value. * @return {Object} Map with view parameters (view and viewPosition). */ - parseViewParam_: function(paramValue) { - var viewModeComponents = paramValue.toLowerCase().split(','); + parseViewParam_(paramValue) { + const viewModeComponents = paramValue.toLowerCase().split(','); if (viewModeComponents.length < 1) return {}; - var params = {}; - var viewMode = viewModeComponents[0]; - var acceptsPositionParam; + const params = {}; + const viewMode = viewModeComponents[0]; + let acceptsPositionParam; if (viewMode === 'fit') { params['view'] = FittingType.FIT_TO_PAGE; acceptsPositionParam = false; @@ -80,12 +83,12 @@ if (!acceptsPositionParam || viewModeComponents.length < 2) return params; - var position = parseFloat(viewModeComponents[1]); - if (!isNaN(position)) + const position = parseFloat(viewModeComponents[1]); + if (!Number.isNaN(position)) params['viewPosition'] = position; return params; - }, + } /** * Parse the parameters encoded in the fragment of a URL into a dictionary. @@ -93,14 +96,14 @@ * @param {string} url to parse * @return {Object} Key-value pairs of URL parameters */ - parseUrlParams_: function(url) { - var params = {}; + parseUrlParams_(url) { + const params = {}; - var paramIndex = url.search('#'); + const paramIndex = url.search('#'); if (paramIndex == -1) return params; - var paramTokens = url.substring(paramIndex + 1).split('&'); + const paramTokens = url.substring(paramIndex + 1).split('&'); if ((paramTokens.length == 1) && (paramTokens[0].search('=') == -1)) { // Handle the case of http://foo.com/bar#NAMEDDEST. This is not // explicitly mentioned except by example in the Adobe @@ -109,15 +112,15 @@ return params; } - for (var i = 0; i < paramTokens.length; ++i) { - var keyValueSplit = paramTokens[i].split('='); + for (let paramToken of paramTokens) { + const keyValueSplit = paramToken.split('='); if (keyValueSplit.length != 2) continue; params[keyValueSplit[0]] = keyValueSplit[1]; } return params; - }, + } /** * Parse PDF url parameters used for controlling the state of UI. These need @@ -126,15 +129,15 @@ * @param {string} url that needs to be parsed. * @return {Object} parsed url parameters. */ - getUiUrlParams: function(url) { - var params = this.parseUrlParams_(url); - var uiParams = {toolbar: true}; + getUiUrlParams(url) { + const params = this.parseUrlParams_(url); + const uiParams = {toolbar: true}; if ('toolbar' in params && params['toolbar'] == 0) uiParams.toolbar = false; return uiParams; - }, + } /** * Parse PDF url parameters. These parameters are mentioned in the url @@ -144,16 +147,16 @@ * @param {string} url that needs to be parsed. * @param {Function} callback function to be called with viewport info. */ - getViewportFromUrlParams: function(url, callback) { - var params = {}; + getViewportFromUrlParams(url, callback) { + const params = {}; params['url'] = url; - var urlParams = this.parseUrlParams_(url); + const urlParams = this.parseUrlParams_(url); if ('page' in urlParams) { // |pageNumber| is 1-based, but goToPage() take a zero-based page number. - var pageNumber = parseInt(urlParams['page'], 10); - if (!isNaN(pageNumber) && pageNumber > 0) + const pageNumber = parseInt(urlParams['page'], 10); + if (!Number.isNaN(pageNumber) && pageNumber > 0) params['page'] = pageNumber - 1; } @@ -165,11 +168,14 @@ if (params.page === undefined && 'nameddest' in urlParams) { this.outstandingRequests_.push({callback: callback, params: params}); - this.getNamedDestinationsFunction_(urlParams['nameddest']); + this.postMessageCallback_({ + type: 'getNamedDestination', + namedDestination: urlParams['nameddest'] + }); } else { callback(params); } - }, + } /** * This is called when a named destination is received and the page number @@ -177,12 +183,12 @@ * @param {number} pageNumber The page corresponding to the named destination * requested. */ - onNamedDestinationReceived: function(pageNumber) { - var outstandingRequest = this.outstandingRequests_.shift(); + onNamedDestinationReceived(pageNumber) { + const outstandingRequest = this.outstandingRequests_.shift(); if (pageNumber != -1) outstandingRequest.params.page = pageNumber; outstandingRequest.callback(outstandingRequest.params); - }, + } }; }());
diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js index 4a8cb93..029f5b2 100644 --- a/chrome/browser/resources/pdf/pdf.js +++ b/chrome/browser/resources/pdf/pdf.js
@@ -106,15 +106,20 @@ this.isUserInitiatedEvent_ = true; /** - * @type {PDFMetrics} + * @type {!PDFMetrics} */ this.metrics = (chrome.metricsPrivate ? new PDFMetricsImpl() : new PDFMetricsDummy()); this.metrics.onDocumentOpened(); + /** + * @private {!PDFCoordsTransformer} + */ + this.coordsTransformer_ = + new PDFCoordsTransformer(this.postMessage_.bind(this)); + // Parse open pdf parameters. - this.paramsParser_ = - new OpenPDFParamsParser(this.getNamedDestination_.bind(this)); + this.paramsParser_ = new OpenPDFParamsParser(this.postMessage_.bind(this)); var toolbarEnabled = this.paramsParser_.getUiUrlParams(this.originalUrl_).toolbar && !this.isPrintPreview_; @@ -224,9 +229,6 @@ this.toolbar_.docTitle = getFilenameFromURL(this.originalUrl_); } - this.coordsTransformer_ = - new PDFCoordsTransformer(this.plugin_.postMessage.bind(this.plugin_)); - document.body.addEventListener('change-page', e => { this.viewport_.goToPage(e.detail.page); if (e.detail.origin == 'bookmark') @@ -391,7 +393,7 @@ return; case 65: // 'a' key. if (e.ctrlKey || e.metaKey) { - this.plugin_.postMessage({type: 'selectAll'}); + this.postMessage_({type: 'selectAll'}); // Since we do selection ourselves. e.preventDefault(); } @@ -451,7 +453,7 @@ */ rotateClockwise_: function() { this.metrics.onRotation(); - this.plugin_.postMessage({type: 'rotateClockwise'}); + this.postMessage_({type: 'rotateClockwise'}); }, /** @@ -460,7 +462,7 @@ */ rotateCounterClockwise_: function() { this.metrics.onRotation(); - this.plugin_.postMessage({type: 'rotateCounterclockwise'}); + this.postMessage_({type: 'rotateCounterclockwise'}); }, /** @@ -488,7 +490,7 @@ * Notify the plugin to print. */ print_: function() { - this.plugin_.postMessage({type: 'print'}); + this.postMessage_({type: 'print'}); }, /** @@ -496,17 +498,7 @@ * Notify the plugin to save. */ save_: function() { - this.plugin_.postMessage({type: 'save'}); - }, - - /** - * Fetches the page number corresponding to the given named destination from - * the plugin. - * @param {string} name The namedDestination to fetch page number from plugin. - */ - getNamedDestination_: function(name) { - this.plugin_.postMessage( - {type: 'getNamedDestination', namedDestination: name}); + this.postMessage_({type: 'save'}); }, /** @@ -630,12 +622,22 @@ * @param {Object} event a password-submitted event. */ onPasswordSubmitted_: function(event) { - this.plugin_.postMessage( + this.postMessage_( {type: 'getPasswordComplete', password: event.detail.password}); }, /** * @private + * Post a message to the PPAPI plugin. Some messages will cause an async reply + * to be received through handlePluginMessage_(). + * @param {Object} message Message to post. + */ + postMessage_: function(message) { + this.plugin_.postMessage(message); + }, + + /** + * @private * An event handler for handling message events received from the plugin. * @param {MessageObject} message a message event. */ @@ -747,13 +749,13 @@ * reacting to scroll events while zoom is taking place to avoid flickering. */ beforeZoom_: function() { - this.plugin_.postMessage({type: 'stopScrolling'}); + this.postMessage_({type: 'stopScrolling'}); if (this.viewport_.pinchPhase == Viewport.PinchPhase.PINCH_START) { var position = this.viewport_.position; var zoom = this.viewport_.zoom; var pinchPhase = this.viewport_.pinchPhase; - this.plugin_.postMessage({ + this.postMessage_({ type: 'viewport', userInitiated: true, zoom: zoom, @@ -776,7 +778,7 @@ var pinchCenter = this.viewport_.pinchCenter || {x: 0, y: 0}; var pinchPhase = this.viewport_.pinchPhase; - this.plugin_.postMessage({ + this.postMessage_({ type: 'viewport', userInitiated: this.isUserInitiatedEvent_, zoom: zoom, @@ -935,7 +937,7 @@ case 'getSelectedText': case 'print': case 'selectAll': - this.plugin_.postMessage(message.data); + this.postMessage_(message.data); break; } }, @@ -952,7 +954,7 @@ switch (message.data.type.toString()) { case 'loadPreviewPage': - this.plugin_.postMessage(message.data); + this.postMessage_(message.data); return true; case 'resetPrintPreviewMode': this.loadState_ = LoadState.LOADING; @@ -977,7 +979,7 @@ this.pageIndicator_.pageLabels = message.data.pageNumbers; - this.plugin_.postMessage({ + this.postMessage_({ type: 'resetPrintPreviewMode', url: message.data.url, grayscale: message.data.grayscale,
diff --git a/chrome/browser/resources/print_preview/new/button_css.html b/chrome/browser/resources/print_preview/new/button_css.html index d3355544..77481fa 100644 --- a/chrome/browser/resources/print_preview/new/button_css.html +++ b/chrome/browser/resources/print_preview/new/button_css.html
@@ -13,13 +13,13 @@ <if expr="not is_ios"> button:enabled:hover { background-image: linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0); - @apply(--print-preview-hover); + @apply --print-preview-hover; } </if> button:enabled:active { background-image: linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7); - @apply(--print-preview-active); + @apply --print-preview-active; } </style> </template>
diff --git a/chrome/browser/resources/print_preview/new/checkbox_radio_css.html b/chrome/browser/resources/print_preview/new/checkbox_radio_css.html index f2564079..159ad3c 100644 --- a/chrome/browser/resources/print_preview/new/checkbox_radio_css.html +++ b/chrome/browser/resources/print_preview/new/checkbox_radio_css.html
@@ -48,14 +48,14 @@ [type='radio']) { background-image: linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0); - @apply(--print-preview-hover); + @apply --print-preview-hover; } </if> input:enabled:active:-webkit-any([type='checkbox'], [type='radio']) { background-image: linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7); - @apply(--print-preview-active); + @apply --print-preview-active; } input:disabled:-webkit-any([type='checkbox'],
diff --git a/chrome/browser/resources/print_preview/new/select_css.html b/chrome/browser/resources/print_preview/new/select_css.html index 5a316158..04838c08b 100644 --- a/chrome/browser/resources/print_preview/new/select_css.html +++ b/chrome/browser/resources/print_preview/new/select_css.html
@@ -21,14 +21,14 @@ select:enabled:hover { background-image: url(chrome://resources/images/select.png), linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0); - @apply(--print-preview-hover); + @apply --print-preview-hover; } </if> select:enabled:active { background-image: url(chrome://resources/images/select.png), linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7); - @apply(--print-preview-active); + @apply --print-preview-active; } select:disabled {
diff --git a/chrome/browser/resources/settings/about_page/about_page.html b/chrome/browser/resources/settings/about_page/about_page.html index 42a110c6..cf0b5bc 100644 --- a/chrome/browser/resources/settings/about_page/about_page.html +++ b/chrome/browser/resources/settings/about_page/about_page.html
@@ -78,7 +78,7 @@ <if expr="_google_chrome and is_macosx"> #promoteUpdater[disabled] { - @apply(--cr-secondary-text); + @apply --cr-secondary-text; } </if> </style>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html index 94029ec4..80ab0b6 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -46,7 +46,7 @@ --paper-button: { text-transform: none; } - @apply(--settings-actionable); + @apply --settings-actionable; align-items: center; display: flex; margin-bottom: 3px; @@ -56,7 +56,7 @@ } #secondaryUserBanner { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; align-items: center; background-color: white; border-radius: 2px;
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.html b/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.html index 6ca9d1b..ee5afe86 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.html +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.html
@@ -15,7 +15,7 @@ <template> <style include="settings-shared iron-flex"> .container { - @apply(--settings-list-frame-padding); + @apply --settings-list-frame-padding; display: flex; flex-direction: column; min-height: 10px; @@ -27,7 +27,7 @@ } paper-spinner-lite { - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; } #onOff {
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.html b/chrome/browser/resources/settings/controls/controlled_radio_button.html index 10b1bca..c78f992 100644 --- a/chrome/browser/resources/settings/controls/controlled_radio_button.html +++ b/chrome/browser/resources/settings/controls/controlled_radio_button.html
@@ -12,7 +12,7 @@ :host { --ink-to-circle: calc((var(--paper-radio-button-ink-size) - var(--paper-radio-button-size)) / 2); - @apply(--settings-actionable); + @apply --settings-actionable; align-items: center; display: flex; outline: none; @@ -24,7 +24,7 @@ } #label { - color: var(--paper-radio-button-label-color, --primary-text-color); + color: var(--paper-radio-button-label-color, var(--primary-text-color)); } .circle, @@ -53,11 +53,12 @@ .circle { border: 2px solid var(--paper-radio-button-unchecked-color, - --primary-text-color); + var(--primary-text-color)); } :host([checked]) .circle { - border-color: var(--paper-radio-button-checked-color, --primary-color); + border-color: var(--paper-radio-button-checked-color, + var(--primary-color)); } .disc { @@ -69,23 +70,23 @@ :host([checked]) .disc { background-color: var(--paper-radio-button-checked-color, - --primary-color); + var(--primary-color)); transform: scale(0.5); } paper-ripple { color: var(--paper-radio-button-unchecked-ink-color, - --primary-text-color); + var(--primary-text-color)); opacity: .6; } :host([checked]) paper-ripple { color: var(--paper-radio-button-checked-ink-color, - --primary-text-color); + var(--primary-text-color)); } :host(:not([controlled_])) { - @apply(--settings-actionable); + @apply --settings-actionable; } :host([controlled_]) { @@ -100,12 +101,12 @@ :host([controlled_]) .circle { border-color: var(--paper-radio-button-unchecked-color, - --primary-text-color); + var(--primary-text-color)); } :host([controlled_][checked]) .disc { background-color: var(--paper-radio-button-unchecked-color, - --primary-text-color); + var(--primary-text-color)); } :host([controlled_]) #labelWrapper {
diff --git a/chrome/browser/resources/settings/controls/extension_controlled_indicator.html b/chrome/browser/resources/settings/controls/extension_controlled_indicator.html index ff53538c..1511d31 100644 --- a/chrome/browser/resources/settings/controls/extension_controlled_indicator.html +++ b/chrome/browser/resources/settings/controls/extension_controlled_indicator.html
@@ -17,7 +17,7 @@ } img { - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; -webkit-margin-end: 16px; }
diff --git a/chrome/browser/resources/settings/controls/important_site_checkbox.html b/chrome/browser/resources/settings/controls/important_site_checkbox.html index 0a0dd1b..e70da80b 100644 --- a/chrome/browser/resources/settings/controls/important_site_checkbox.html +++ b/chrome/browser/resources/settings/controls/important_site_checkbox.html
@@ -20,7 +20,7 @@ } paper-checkbox:not([checked]) .secondary { - @apply(--settings-secondary-unchecked); + @apply --settings-secondary-unchecked; } .middot { @@ -28,7 +28,7 @@ } .label { - @apply(--settings-checkbox-label); + @apply --settings-checkbox-label; } </style> <div id="outerRow">
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.html b/chrome/browser/resources/settings/controls/settings_checkbox.html index b46ee71..0563536 100644 --- a/chrome/browser/resources/settings/controls/settings_checkbox.html +++ b/chrome/browser/resources/settings/controls/settings_checkbox.html
@@ -30,7 +30,7 @@ } paper-checkbox:not([checked]) .secondary { - @apply(--settings-secondary-unchecked); + @apply --settings-secondary-unchecked; } cr-policy-pref-indicator { @@ -38,7 +38,7 @@ } .label { - @apply(--settings-checkbox-label); + @apply --settings-checkbox-label; } </style> <div id="outerRow" noSubLabel$="[[!hasSubLabel_(subLabel, subLabelHtml)]]">
diff --git a/chrome/browser/resources/settings/controls/settings_toggle_button.html b/chrome/browser/resources/settings/controls/settings_toggle_button.html index 7cdb86fd..145cc4c 100644 --- a/chrome/browser/resources/settings/controls/settings_toggle_button.html +++ b/chrome/browser/resources/settings/controls/settings_toggle_button.html
@@ -10,7 +10,7 @@ <template> <style include="settings-shared iron-flex"> :host { - @apply(--cr-section); + @apply --cr-section; } :host(.first), @@ -29,7 +29,7 @@ } :host([elide-label]) .label { - @apply(--settings-text-elide); + @apply --settings-text-elide; } #outerRow {
diff --git a/chrome/browser/resources/settings/device_page/display_layout.html b/chrome/browser/resources/settings/device_page/display_layout.html index 289ebf9..7b3ce0b3 100644 --- a/chrome/browser/resources/settings/device_page/display_layout.html +++ b/chrome/browser/resources/settings/device_page/display_layout.html
@@ -54,7 +54,7 @@ } .display.elevate { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; } </style> <div id="displayArea" on-iron-resize="calculateVisualScale_">
diff --git a/chrome/browser/resources/settings/device_page/stylus.html b/chrome/browser/resources/settings/device_page/stylus.html index 9aa157e..c6c7d5b 100644 --- a/chrome/browser/resources/settings/device_page/stylus.html +++ b/chrome/browser/resources/settings/device_page/stylus.html
@@ -19,7 +19,7 @@ paper-spinner-lite { margin-left: 12px; - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; } cr-policy-indicator {
diff --git a/chrome/browser/resources/settings/icons.html b/chrome/browser/resources/settings/icons.html index 6d5d33a..4fae987 100644 --- a/chrome/browser/resources/settings/icons.html +++ b/chrome/browser/resources/settings/icons.html
@@ -10,9 +10,7 @@ <defs> <!-- Ads icon in the Content Settings --> <g id="ads"> - <path d="M19,3H5C3.89,3,3,3.9,3,5v14c0,1.1,0.89,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M11,15H9.5v-1.5h-2V15H6v-4.5V9h1.5h2H10h1V15z M18,14c0,0.55-0.45,1-1,1h-4V9h4c0.55,0,1,0.45,1,1V14z"></path> - <rect x="7.5" y="10.5" width="2" height="1.5"></rect> - <rect x="14.5" y="10.5" width="2" height="3"></rect> + <path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm0 14H5V8h14v10z"></path> </g> <!-- Cookie SVG obtained from rolfe@ -->
diff --git a/chrome/browser/resources/settings/internet_page/internet_subpage.html b/chrome/browser/resources/settings/internet_page/internet_subpage.html index 976a5d2..adff19f 100644 --- a/chrome/browser/resources/settings/internet_page/internet_subpage.html +++ b/chrome/browser/resources/settings/internet_page/internet_subpage.html
@@ -65,12 +65,12 @@ } #gmscore-notifications-device-string { - @apply(--cr-secondary-text); + @apply --cr-secondary-text; margin-top: 5px; } #gmscore-notifications-instructions { - @apply(--cr-secondary-text); + @apply --cr-secondary-text; -webkit-padding-start: 15px; margin: 0; }
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html index 02b87b20..5a4d075f 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html +++ b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html
@@ -18,7 +18,7 @@ <template> <style include="settings-shared action-link iron-flex"> .list-frame { - @apply(--settings-list-frame-padding); + @apply --settings-list-frame-padding; } .list-frame > div { @@ -26,7 +26,7 @@ } #outer { - @apply(--settings-list-frame-padding); + @apply --settings-list-frame-padding; max-height: 355px; /** Enough height to show six entries. */ }
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html index 37c189b..3dcc9014 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html
@@ -51,7 +51,7 @@ transform: scale(0.75); transform-origin: left; width: 133%; - @apply(--paper-input-container-label-floating); + @apply --paper-input-container-label-floating; } :host-context([dir=rtl]) #select-label {
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html index 7b314c1..85f23b3 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
@@ -22,7 +22,7 @@ }; --paper-input-container-label-focus: { - color: var(--paper-input-container-color, --secondary-text-color); + color: var(--secondary-text-color); }; }
diff --git a/chrome/browser/resources/settings/people_page/fingerprint_list.html b/chrome/browser/resources/settings/people_page/fingerprint_list.html index 6c62e3e..d91e994 100644 --- a/chrome/browser/resources/settings/people_page/fingerprint_list.html +++ b/chrome/browser/resources/settings/people_page/fingerprint_list.html
@@ -29,7 +29,7 @@ } .body { - @apply(--settings-list-frame-padding); + @apply --settings-list-frame-padding; } .list-item {
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.html b/chrome/browser/resources/settings/people_page/lock_screen.html index cdaa250..05d0901 100644 --- a/chrome/browser/resources/settings/people_page/lock_screen.html +++ b/chrome/browser/resources/settings/people_page/lock_screen.html
@@ -59,7 +59,7 @@ } #easyUnlockSettingsCollapsible { - @apply(--settings-list-frame-padding); + @apply --settings-list-frame-padding; } .no-padding {
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.html b/chrome/browser/resources/settings/people_page/sync_account_control.html index 08d4e2f6..5bbbc2c5 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.html +++ b/chrome/browser/resources/settings/people_page/sync_account_control.html
@@ -3,6 +3,8 @@ <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/notification-icons.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="profile_info_browser_proxy.html"> <link rel="import" href="sync_browser_proxy.html"> @@ -19,8 +21,6 @@ } .account-icon { - background: url(chrome://theme/IDR_PROFILE_AVATAR_PLACEHOLDER_LARGE) - center / cover no-repeat; border-radius: 20px; flex-shrink: 0; height: 40px; @@ -44,6 +44,39 @@ display: flex; flex-direction: column; } + + #avatar-container { + position: relative; + } + + #sync-logo-container { + align-items: center; + background: var(--google-blue-500); + border: 2px solid white; + border-radius: 50%; + bottom: 0; + display: flex; + height: 16px; + position: absolute; + right: -6px; + width: 16px; + } + + :host-context([dir='rtl']) #sync-logo-container { + left: -6px; + right: initial; + } + + #sync-logo-container[syncing] { + background: green; + } + + #sync-logo-container iron-icon { + fill: white; + height: 12px; + margin: auto; + width: 12px; + } </style> <!-- TODO(scottchen): figure out what to show if sign-in (not just sync) is not even allowed by policy (crbug/807061). --> @@ -61,7 +94,13 @@ </div> <template is="dom-if" if="[[shouldShowAvatarRow_]]"> <div class="settings-box first two-line"> - <img class="account-icon" src="[[shownAccount_.image]]"> + <div id="avatar-container"> + <img class="account-icon" + src="[[getAccountImageSrc_(shownAccount_.avatarImage)]]"> + <div id="sync-logo-container" syncing$="[[syncStatus.signedIn]]"> + <iron-icon icon="notification:sync"></iron-icon> + </div> + </div> <div class="middle two-line no-min-width"> <div class="flex text-elide"> <span> @@ -94,12 +133,14 @@ <dialog is="cr-action-menu" id="menu"> <template is="dom-repeat" items="[[storedAccounts_]]"> <button class="dropdown-item" on-tap="onAccountTap_" slot="item"> - <img class="account-icon small" src="[[item.image]]"> + <img class="account-icon small" + src="[[getAccountImageSrc_(item.avatarImage)]]"> <span class="email">[[item.email]]</span> </button> </template> <button class="dropdown-item" on-tap="onSigninTap_" slot="item"> - <div class="account-icon small"></div> + <img class="account-icon small" + src="chrome://theme/IDR_PROFILE_AVATAR_PLACEHOLDER_LARGE"> <span class="email">$i18n{useAnotherAccount}</span> </button> </dialog>
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.js b/chrome/browser/resources/settings/people_page/sync_account_control.js index 373647d..53649d4 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.js +++ b/chrome/browser/resources/settings/people_page/sync_account_control.js
@@ -78,6 +78,16 @@ }, /** + * @param {?string} image + * @return {string} + * @private + */ + getAccountImageSrc_: function(image) { + // image can be undefined if the account has not set an avatar photo. + return image || 'chrome://theme/IDR_PROFILE_AVATAR_PLACEHOLDER_LARGE'; + }, + + /** * @param {!Array<!settings.StoredAccount>} accounts * @private */
diff --git a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js index ddd3f35..b15ed69 100644 --- a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js
@@ -11,8 +11,8 @@ /** * @typedef {{fullName: (string|undefined), - * email: !string, - * image: (string|undefined)}} + * email: string, + * avatarImage: (string|undefined)}} * @see chrome/browser/ui/webui/settings/people_handler.cc */ settings.StoredAccount; @@ -183,7 +183,7 @@ /** * Start syncing with an account, specified by its email. - * @param {!string} email + * @param {string} email */ startSyncingWithEmail(email) {}
diff --git a/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html b/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html index 029074eb..026ed96e 100644 --- a/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html +++ b/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html
@@ -89,7 +89,7 @@ padding: 0 24px; text-align: start; width: 100%; - @apply(--settings-actionable); + @apply --settings-actionable; } .list-item:focus {
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_list.html b/chrome/browser/resources/settings/search_engines_page/search_engines_list.html index 507bf487..1e6af9d 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_list.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_list.html
@@ -23,7 +23,7 @@ } #outer { - @apply(--settings-list-frame-padding); + @apply --settings-list-frame-padding; } settings-search-engine-entry {
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html index eb06d3c..a6b3b95 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
@@ -19,7 +19,7 @@ .extension-engines, #noOtherEngines, .no-search-results { - @apply(--settings-list-frame-padding); + @apply --settings-list-frame-padding; } settings-omnibox-extension-entry {
diff --git a/chrome/browser/resources/settings/settings_page/settings_section.html b/chrome/browser/resources/settings/settings_page/settings_section.html index 644879a..3daf513 100644 --- a/chrome/browser/resources/settings/settings_page/settings_section.html +++ b/chrome/browser/resources/settings/settings_page/settings_section.html
@@ -20,13 +20,13 @@ } #header .title { - @apply(--cr-section-text); + @apply --cr-section-text; margin-bottom: 0; margin-top: var(--settings-page-vertical-margin); } #card { - @apply(--shadow-elevation-2dp); + @apply --shadow-elevation-2dp; background-color: white; border-radius: 2px; flex: 1; @@ -39,7 +39,7 @@ :host(.expanding) #card, :host(.collapsing) #card, :host(.expanded) #card { - @apply(--shadow-elevation-4dp); + @apply --shadow-elevation-4dp; overflow: hidden; /* A stacking context constrains sliding sub-pages to the card. */ z-index: 0;
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.html b/chrome/browser/resources/settings/settings_page/settings_subpage.html index 12b26d2..bb1e8ca 100644 --- a/chrome/browser/resources/settings/settings_page/settings_subpage.html +++ b/chrome/browser/resources/settings/settings_page/settings_subpage.html
@@ -26,7 +26,7 @@ } #learnMore { - @apply(--cr-paper-icon-button-margin); + @apply --cr-paper-icon-button-margin; align-items: center; display: flex; height: var(--cr-icon-ripple-size); @@ -42,12 +42,12 @@ } paper-spinner-lite { - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; } h1 { flex: 1; /* Push other items to the end. */ - @apply(--cr-title-text); + @apply --cr-title-text; } settings-subpage-search {
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html index 36f4372..c4a18af 100644 --- a/chrome/browser/resources/settings/settings_shared_css.html +++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -105,7 +105,7 @@ } paper-toggle-button { - @apply(--settings-actionable); + @apply --settings-actionable; height: var(--settings-row-min-height); user-select: none; /* Prevents text selection while dragging. */ width: 36px; @@ -154,7 +154,7 @@ /* See also: .no-min-width below. */ .text-elide { - @apply(--settings-text-elide); + @apply --settings-text-elide; } /* By default, flexbox children have min-width calculated to be the width @@ -174,7 +174,7 @@ * outside of a settings-box. A list-frame is likely to follow a * settings box. */ .list-frame { - @apply(--settings-list-frame-padding); + @apply --settings-list-frame-padding; align-items: center; display: block; } @@ -230,7 +230,7 @@ /* A settings-box is a horizontal row of text or controls within a * setting section (page or subpage). */ .settings-box { - @apply(--cr-section); + @apply --cr-section; } .settings-box.two-line { @@ -273,7 +273,7 @@ /* The lower line of text in a two-line row. */ .secondary { - @apply(--cr-secondary-text); + @apply --cr-secondary-text; } /* The |:empty| CSS selector only works when there is no whitespace.
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chrome/browser/resources/settings/settings_ui/settings_ui.html index 7aca114c..9031db8 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.html +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -24,7 +24,7 @@ <template> <style include="settings-shared"> :host { - @apply(--layout-fit); + @apply --layout-fit; color: var(--primary-text-color); display: flex; flex-direction: column; @@ -38,7 +38,7 @@ } cr-toolbar { - @apply(--layout-center); + @apply --layout-center; --iron-icon-fill-color: white; background-color: var(--google-blue-700); color: white;
diff --git a/chrome/browser/resources/settings/site_settings/site_data.html b/chrome/browser/resources/settings/site_settings/site_data.html index c50d941..403533ce 100644 --- a/chrome/browser/resources/settings/site_settings/site_data.html +++ b/chrome/browser/resources/settings/site_settings/site_data.html
@@ -25,7 +25,7 @@ } paper-spinner-lite { - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; opacity: 0; transition-delay: 1s; }
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc index a4305a4..53e46ac 100644 --- a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc +++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -90,7 +90,11 @@ bool UrlCheckerDelegateImpl::ShouldSkipRequestCheck( content::ResourceContext* resource_context, - const GURL& original_url) { + const GURL& original_url, + int frame_tree_node_id, + int render_process_id, + int render_frame_id, + bool originated_from_service_worker) { // When DataReductionProxyResourceThrottle is enabled for a request, it is // responsible for checking whether the resource is safe, so we skip // SafeBrowsing URL checks in that case.
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.h b/chrome/browser/safe_browsing/url_checker_delegate_impl.h index d86013e..58fc12d 100644 --- a/chrome/browser/safe_browsing/url_checker_delegate_impl.h +++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.h
@@ -35,7 +35,11 @@ bool has_user_gesture) override; bool IsUrlWhitelisted(const GURL& url) override; bool ShouldSkipRequestCheck(content::ResourceContext* resource_context, - const GURL& url) override; + const GURL& original_url, + int frame_tree_node_id, + int render_process_id, + int render_frame_id, + bool originated_from_service_worker) override; const SBThreatTypeSet& GetThreatTypes() override; SafeBrowsingDatabaseManager* GetDatabaseManager() override; BaseUIManager* GetUIManager() override;
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc index 4dac09d..56bc6f678 100644 --- a/chrome/browser/signin/chrome_signin_client.cc +++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -31,7 +31,6 @@ #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_util.h" #include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/user_manager.h" #include "chrome/browser/web_data_service_factory.h" #include "chrome/common/channel_info.h" #include "chrome/common/features.h" @@ -60,6 +59,8 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "components/user_manager/known_user.h" #include "components/user_manager/user_manager.h" +#else +#include "chrome/browser/ui/user_manager.h" #endif #if !defined(OS_ANDROID)
diff --git a/chrome/browser/site_details_browsertest.cc b/chrome/browser/site_details_browsertest.cc index 065f95ac..d40711e 100644 --- a/chrome/browser/site_details_browsertest.cc +++ b/chrome/browser/site_details_browsertest.cc
@@ -245,49 +245,6 @@ return extension; } - // Creates a V2 platform app that loads a web iframe in the app's sandbox - // page. - // TODO(lazyboy): Deprecate this behavior in https://crbug.com/615585. - void CreateAppWithSandboxPage(const std::string& name) { - std::unique_ptr<TestExtensionDir> dir(new TestExtensionDir); - - DictionaryBuilder manifest; - manifest.Set("name", name) - .Set("version", "1.0") - .Set("manifest_version", 2) - .Set("sandbox", - DictionaryBuilder() - .Set("pages", ListBuilder().Append("sandbox.html").Build()) - .Build()) - .Set("app", - DictionaryBuilder() - .Set("background", - DictionaryBuilder() - .Set("scripts", - ListBuilder().Append("background.js").Build()) - .Build()) - .Build()); - - dir->WriteFile(FILE_PATH_LITERAL("background.js"), - "var sandboxFrame = document.createElement('iframe');" - "sandboxFrame.src = 'sandbox.html';" - "document.body.appendChild(sandboxFrame);"); - - std::string iframe_url = - embedded_test_server()->GetURL("/title1.html").spec(); - dir->WriteFile( - FILE_PATH_LITERAL("sandbox.html"), - base::StringPrintf("<html><body>%s, web iframe:" - " <iframe width=80 height=80 src=%s></iframe>" - "</body></html>", - name.c_str(), iframe_url.c_str())); - dir->WriteManifest(manifest.ToJSON()); - - const Extension* extension = LoadExtension(dir->UnpackedPath()); - EXPECT_TRUE(extension); - temp_dirs_.push_back(std::move(dir)); - } - const Extension* CreateHostedApp(const std::string& name, const GURL& app_url) { std::unique_ptr<TestExtensionDir> dir(new TestExtensionDir); @@ -922,19 +879,6 @@ DependingOnPolicy(0, 2, 2)); } -// Due to http://crbug.com/612711, we are not isolating iframes from platform -// apps with --isolate-extenions. -IN_PROC_BROWSER_TEST_F(SiteDetailsBrowserTest, PlatformAppsNotIsolated) { - // --site-per-process will still isolate iframes from platform apps, so skip - // the test in that case. - if (content::AreAllSitesIsolatedForTesting()) - return; - CreateAppWithSandboxPage("Extension One"); - scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); - details->StartFetchAndWait(); - EXPECT_EQ(0, details->GetOutOfProcessIframeCount()); -} - // Exercises accounting in the case where an extension has two different-site // web iframes. IN_PROC_BROWSER_TEST_F(SiteDetailsBrowserTest, ExtensionWithTwoWebIframes) {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 2c30fd0..b59e60b 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1535,8 +1535,6 @@ "unload_controller.h", "unload_controller_web_contents_delegate.cc", "unload_controller_web_contents_delegate.h", - "user_manager.cc", - "user_manager.h", "webui/app_launcher_login_handler.cc", "webui/app_launcher_login_handler.h", "webui/bookmarks_ui.cc", @@ -1625,8 +1623,6 @@ "webui/policy_tool_ui.h", "webui/policy_tool_ui_handler.cc", "webui/policy_tool_ui_handler.h", - "webui/profile_helper.cc", - "webui/profile_helper.h", "webui/profile_info_watcher.cc", "webui/profile_info_watcher.h", "webui/set_as_default_browser_ui_win.cc", @@ -2187,6 +2183,8 @@ "sync/one_click_signin_sync_observer.h", "sync/one_click_signin_sync_starter.cc", "sync/one_click_signin_sync_starter.h", + "user_manager.cc", + "user_manager.h", "views/close_bubble_on_tab_activation_helper.cc", "views/close_bubble_on_tab_activation_helper.h", "views/external_protocol_dialog.cc", @@ -2200,6 +2198,8 @@ "views/profiles/profile_chooser_view.h", "webui/app_launcher_page_ui.cc", "webui/app_launcher_page_ui.h", + "webui/profile_helper.cc", + "webui/profile_helper.h", "webui/settings/settings_default_browser_handler.cc", "webui/settings/settings_default_browser_handler.h", "webui/settings/system_handler.cc", @@ -2246,6 +2246,8 @@ "views/frame/avatar_button_manager.h", "views/profiles/avatar_button.cc", "views/profiles/avatar_button.h", + "views/profiles/user_manager_view.cc", + "views/profiles/user_manager_view.h", ] deps += [ "//ui/views:features" ] } @@ -2495,8 +2497,6 @@ "cocoa/password_reuse_warning_dialog_cocoa.mm", "cocoa/password_reuse_warning_view_controller.h", "cocoa/password_reuse_warning_view_controller.mm", - "cocoa/passwords/password_prompt_view_bridge.h", - "cocoa/passwords/password_prompt_view_bridge.mm", "cocoa/permission_bubble/chooser_bubble_ui_views_mac.mm", "cocoa/session_crashed_bubble.mm", "cocoa/simple_message_box_bridge_views.mm", @@ -3126,8 +3126,6 @@ "views/permission_bubble/permission_prompt_impl_views.cc", "views/profiles/profile_indicator_icon.cc", "views/profiles/profile_indicator_icon.h", - "views/profiles/user_manager_view.cc", - "views/profiles/user_manager_view.h", "views/proximity_auth/proximity_auth_error_bubble_view.cc", "views/proximity_auth/proximity_auth_error_bubble_view.h", "views/sad_tab_view.cc",
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate.cc b/chrome/browser/ui/app_list/app_list_controller_delegate.cc index dfe9c6b..49b959f 100644 --- a/chrome/browser/ui/app_list/app_list_controller_delegate.cc +++ b/chrome/browser/ui/app_list/app_list_controller_delegate.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" +#include <utility> + #include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "chrome/browser/extensions/extension_util.h" @@ -44,12 +46,14 @@ } // namespace +AppListControllerDelegate::AppListControllerDelegate() + : weak_ptr_factory_(this) {} + AppListControllerDelegate::~AppListControllerDelegate() {} -void AppListControllerDelegate::ViewClosing() {} - -gfx::Rect AppListControllerDelegate::GetAppInfoDialogBounds() { - return gfx::Rect(); +void AppListControllerDelegate::GetAppInfoDialogBounds( + GetAppInfoDialogBoundsCallback callback) { + std::move(callback).Run(gfx::Rect()); } void AppListControllerDelegate::OnShowChildDialog() { @@ -87,8 +91,6 @@ Profile* profile, const std::string& extension_id) { DCHECK(CanDoShowAppInfoFlow()); - const extensions::Extension* extension = GetExtension(profile, extension_id); - DCHECK(extension); OnShowChildDialog(); @@ -98,10 +100,18 @@ // Since the AppListControllerDelegate is a leaky singleton, passing its raw // pointer around is OK. - ShowAppInfoInAppList( - GetAppInfoDialogBounds(), profile, extension, - base::Bind(&AppListControllerDelegate::OnCloseChildDialog, - base::Unretained(this))); + GetAppInfoDialogBounds(base::BindOnce( + [](base::WeakPtr<AppListControllerDelegate> self, Profile* profile, + const std::string& extension_id, const gfx::Rect& bounds) { + const extensions::Extension* extension = + GetExtension(profile, extension_id); + DCHECK(extension); + ShowAppInfoInAppList( + bounds, profile, extension, + base::BindRepeating(&AppListControllerDelegate::OnCloseChildDialog, + self)); + }, + weak_ptr_factory_.GetWeakPtr(), profile, extension_id)); } void AppListControllerDelegate::UninstallApp(Profile* profile,
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate.h b/chrome/browser/ui/app_list/app_list_controller_delegate.h index 0b769b56..acab470 100644 --- a/chrome/browser/ui/app_list/app_list_controller_delegate.h +++ b/chrome/browser/ui/app_list/app_list_controller_delegate.h
@@ -9,6 +9,8 @@ #include <string> +#include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" #include "chrome/common/extensions/extension_constants.h" #include "extensions/common/constants.h" #include "ui/base/page_transition_types.h" @@ -46,21 +48,24 @@ PIN_FIXED }; + AppListControllerDelegate(); virtual ~AppListControllerDelegate(); // Dismisses the view. virtual void DismissView() = 0; - // Handles the view being closed. - virtual void ViewClosing(); + // Gets display ID of app list window. + virtual int64_t GetAppListDisplayId() = 0; + + // Sets display ID of app list window whenever it changes. + virtual void SetAppListDisplayId(int64_t display_id) = 0; // Gets the content bounds of the app info dialog of the app list in the // screen coordinates. On platforms that do not use views, this returns a 0x0 // rectangle. - virtual gfx::Rect GetAppInfoDialogBounds(); - - // Gets display ID of app list window. - virtual int64_t GetAppListDisplayId() = 0; + using GetAppInfoDialogBoundsCallback = + base::OnceCallback<void(const gfx::Rect&)>; + virtual void GetAppInfoDialogBounds(GetAppInfoDialogBoundsCallback callback); // Control of pinning apps. virtual bool IsAppPinned(const std::string& app_id) = 0; @@ -151,6 +156,9 @@ // Called when a search is started using the app list search box. void OnSearchStarted(); + + private: + base::WeakPtrFactory<AppListControllerDelegate> weak_ptr_factory_; }; #endif // CHROME_BROWSER_UI_APP_LIST_APP_LIST_CONTROLLER_DELEGATE_H_
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h index c52867bb..032e3a1 100644 --- a/chrome/browser/ui/app_list/app_list_model_updater.h +++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -109,6 +109,8 @@ virtual size_t BadgedItemCount() = 0; // For SearchModel: virtual bool SearchEngineIsGoogle() = 0; + virtual app_list::SearchResult* FindSearchResult( + const std::string& result_id) = 0; protected: virtual ~AppListModelUpdater() {}
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc index 4eaa263..96e21285 100644 --- a/chrome/browser/ui/app_list/app_list_view_delegate.cc +++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -51,6 +51,7 @@ #include "ui/app_list/app_list_switches.h" #include "ui/app_list/app_list_view_delegate_observer.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/display/types/display_constants.h" #include "ui/keyboard/keyboard_util.h" #include "ui/views/controls/webview/webview.h" @@ -185,22 +186,26 @@ } } -void AppListViewDelegate::OpenSearchResult(app_list::SearchResult* result, +void AppListViewDelegate::OpenSearchResult(const std::string& result_id, int event_flags) { - search_controller_->OpenResult(result, event_flags); + app_list::SearchResult* result = model_updater_->FindSearchResult(result_id); + if (result) + search_controller_->OpenResult(result, event_flags); } -void AppListViewDelegate::InvokeSearchResultAction( - app_list::SearchResult* result, - int action_index, - int event_flags) { - search_controller_->InvokeResultAction(result, action_index, event_flags); +void AppListViewDelegate::InvokeSearchResultAction(const std::string& result_id, + int action_index, + int event_flags) { + app_list::SearchResult* result = model_updater_->FindSearchResult(result_id); + if (result) + search_controller_->InvokeResultAction(result, action_index, event_flags); } -void AppListViewDelegate::ViewShown() { +void AppListViewDelegate::ViewShown(int64_t display_id) { base::RecordAction(base::UserMetricsAction("Launcher_Show")); base::UmaHistogramSparse("Apps.AppListBadgedAppsCount", model_updater_->BadgedItemCount()); + controller_->SetAppListDisplayId(display_id); } void AppListViewDelegate::Dismiss() { @@ -208,7 +213,7 @@ } void AppListViewDelegate::ViewClosing() { - controller_->ViewClosing(); + controller_->SetAppListDisplayId(display::kInvalidDisplayId); } void AppListViewDelegate::GetWallpaperProminentColors(
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.h b/chrome/browser/ui/app_list/app_list_view_delegate.h index 05458098..83831c42 100644 --- a/chrome/browser/ui/app_list/app_list_view_delegate.h +++ b/chrome/browser/ui/app_list/app_list_view_delegate.h
@@ -62,12 +62,11 @@ app_list::AppListModel* GetModel() override; app_list::SearchModel* GetSearchModel() override; void StartSearch(const base::string16& raw_query) override; - void OpenSearchResult(app_list::SearchResult* result, - int event_flags) override; - void InvokeSearchResultAction(app_list::SearchResult* result, + void OpenSearchResult(const std::string& result_id, int event_flags) override; + void InvokeSearchResultAction(const std::string& result_id, int action_index, int event_flags) override; - void ViewShown() override; + void ViewShown(int64_t display_id) override; void Dismiss() override; void ViewClosing() override; void GetWallpaperProminentColors(
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc index eb85384a..247e530 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -238,6 +238,11 @@ chrome_item->ContextMenuItemSelected(command_id, event_flags); } +app_list::SearchResult* ChromeAppListModelUpdater::FindSearchResult( + const std::string& result_id) { + return search_model_->FindSearchResult(result_id); +} + //////////////////////////////////////////////////////////////////////////////// // Methods for AppListSyncableService
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h index 8b72925..9c24e504 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -79,6 +79,8 @@ void ContextMenuItemSelected(const std::string& id, int command_id, int event_flags) override; + app_list::SearchResult* FindSearchResult( + const std::string& result_id) override; // Methods for AppListSyncableService: void AddItemToOemFolder(
diff --git a/chrome/browser/ui/app_list/profile_loader.cc b/chrome/browser/ui/app_list/profile_loader.cc index 32cf8316..5dea8aac 100644 --- a/chrome/browser/ui/app_list/profile_loader.cc +++ b/chrome/browser/ui/app_list/profile_loader.cc
@@ -7,10 +7,13 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "chrome/browser/ui/app_list/profile_store.h" -#include "chrome/browser/ui/user_manager.h" #include "components/keep_alive_registry/keep_alive_types.h" #include "components/keep_alive_registry/scoped_keep_alive.h" +#if !defined(OS_CHROMEOS) +#include "chrome/browser/ui/user_manager.h" +#endif // !defined(OS_CHROMEOS) + ProfileLoader::ProfileLoader(ProfileStore* profile_store) : profile_store_(profile_store), profile_load_sequence_id_(0), @@ -35,9 +38,11 @@ InvalidatePendingProfileLoads(); if (profile_store_->IsProfileLocked(profile_file_path)) { - UserManager::Show(base::FilePath(), - profiles::USER_MANAGER_SELECT_PROFILE_APP_LAUNCHER); - return; +#if !defined(OS_CHROMEOS) + UserManager::Show(base::FilePath(), + profiles::USER_MANAGER_SELECT_PROFILE_APP_LAUNCHER); +#endif // !defined(OS_CHROMEOS) + return; } Profile* profile = profile_store_->GetProfileByPath(profile_file_path);
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc index b4541a1..3101889 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -105,6 +105,15 @@ return search_engine_is_google_; } +app_list::SearchResult* FakeAppListModelUpdater::FindSearchResult( + const std::string& result_id) { + for (auto& result : search_results_) { + if (result->id() == result_id) + return result.get(); + } + return nullptr; +} + void FakeAppListModelUpdater::PublishSearchResults( std::vector<std::unique_ptr<app_list::SearchResult>> results) { search_results_ = std::move(results);
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h index ab55c5c..7278fc1 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -46,6 +46,8 @@ size_t BadgedItemCount() override; // For SearchModel: bool SearchEngineIsGoogle() override; + app_list::SearchResult* FindSearchResult( + const std::string& result_id) override; const std::vector<std::unique_ptr<app_list::SearchResult>>& search_results() const { return search_results_;
diff --git a/chrome/browser/ui/app_list/test/test_app_list_controller_delegate.cc b/chrome/browser/ui/app_list/test/test_app_list_controller_delegate.cc index 92b7ab5..65117cf 100644 --- a/chrome/browser/ui/app_list/test/test_app_list_controller_delegate.cc +++ b/chrome/browser/ui/app_list/test/test_app_list_controller_delegate.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" +#include <utility> + +#include "ui/display/types/display_constants.h" #include "ui/gfx/image/image_skia.h" namespace test { @@ -15,9 +18,11 @@ } int64_t TestAppListControllerDelegate::GetAppListDisplayId() { - return 0; + return display::kInvalidDisplayId; } +void TestAppListControllerDelegate::SetAppListDisplayId(int64_t display_id) {} + void TestAppListControllerDelegate::DismissView() {} bool TestAppListControllerDelegate::IsAppPinned(const std::string& app_id) {
diff --git a/chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h b/chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h index 87c1b95..06fc2ad 100644 --- a/chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h +++ b/chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h
@@ -17,6 +17,7 @@ ~TestAppListControllerDelegate() override; int64_t GetAppListDisplayId() override; + void SetAppListDisplayId(int64_t display_id) override; void DismissView() override; bool IsAppPinned(const std::string& app_id) override; void PinApp(const std::string& app_id) override;
diff --git a/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc b/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc index a6a1b4a..8077f9dd 100644 --- a/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc +++ b/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/ash/app_list/app_list_controller_ash.h" +#include <utility> + #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h" @@ -23,23 +25,25 @@ AppListControllerDelegateAsh::~AppListControllerDelegateAsh() {} -int64_t AppListControllerDelegateAsh::GetAppListDisplayId() { - auto* screen = display::Screen::GetScreen(); - return screen - ? screen->GetDisplayNearestWindow(app_list_presenter_->GetWindow()) - .id() - : display::kInvalidDisplayId; -} - void AppListControllerDelegateAsh::DismissView() { app_list_presenter_->Dismiss(); } -gfx::Rect AppListControllerDelegateAsh::GetAppInfoDialogBounds() { +int64_t AppListControllerDelegateAsh::GetAppListDisplayId() { + return display_id_; +} + +void AppListControllerDelegateAsh::SetAppListDisplayId(int64_t display_id) { + display_id_ = display_id; +} + +void AppListControllerDelegateAsh::GetAppInfoDialogBounds( + GetAppInfoDialogBoundsCallback callback) { app_list::AppListView* app_list_view = app_list_presenter_->GetView(); + gfx::Rect bounds = gfx::Rect(); if (app_list_view) - return app_list_view->GetAppInfoDialogBounds(); - return gfx::Rect(); + bounds = app_list_view->GetAppInfoDialogBounds(); + std::move(callback).Run(bounds); } bool AppListControllerDelegateAsh::IsAppPinned(const std::string& app_id) {
diff --git a/chrome/browser/ui/ash/app_list/app_list_controller_ash.h b/chrome/browser/ui/ash/app_list/app_list_controller_ash.h index 8ed69f1..f46ec2b 100644 --- a/chrome/browser/ui/ash/app_list/app_list_controller_ash.h +++ b/chrome/browser/ui/ash/app_list/app_list_controller_ash.h
@@ -8,9 +8,11 @@ #include <string> #include "ash/public/cpp/shelf_types.h" +#include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" +#include "ui/display/types/display_constants.h" namespace app_list { class AppListPresenterImpl; @@ -22,9 +24,10 @@ ~AppListControllerDelegateAsh() override; // AppListControllerDelegate overrides: - int64_t GetAppListDisplayId() override; void DismissView() override; - gfx::Rect GetAppInfoDialogBounds() override; + int64_t GetAppListDisplayId() override; + void SetAppListDisplayId(int64_t display_id) override; + void GetAppInfoDialogBounds(GetAppInfoDialogBoundsCallback callback) override; bool IsAppPinned(const std::string& app_id) override; bool IsAppOpen(const std::string& app_id) const override; void PinApp(const std::string& app_id) override; @@ -50,6 +53,9 @@ private: ash::ShelfLaunchSource AppListSourceToLaunchSource(AppListSource source); + // The current display id showing the app list. + int64_t display_id_ = display::kInvalidDisplayId; + // Not owned. app_list::AppListPresenterImpl* app_list_presenter_;
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index 6f47ee0..df0a6dd 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/prerender/prerender_manager_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/renderer_host/chrome_navigation_ui_data.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/task_manager/web_contents_tags.h" #include "chrome/browser/ui/browser.h" @@ -303,6 +304,13 @@ load_url_params.suggested_filename = params->suggested_filename; load_url_params.has_user_gesture = params->user_gesture; + // |frame_tree_node_id| is -1 for main frame navigations. + if (params->frame_tree_node_id == -1) { + load_url_params.navigation_ui_data = + ChromeNavigationUIData::CreateForMainFrameNavigation( + target_contents, params->disposition); + } + if (params->uses_post) { load_url_params.load_type = NavigationController::LOAD_TYPE_HTTP_POST; load_url_params.post_data = params->post_data;
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc index 7ffa4fb9..7056256b 100644 --- a/chrome/browser/ui/browser_navigator_browsertest.cc +++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/renderer_host/chrome_navigation_ui_data.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" @@ -27,6 +28,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/omnibox/browser/omnibox_view.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" @@ -35,6 +37,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/bindings_policy.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_frame_navigation_observer.h" #include "content/public/test/test_navigation_observer.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "services/network/public/cpp/resource_request_body.h" @@ -219,6 +222,32 @@ ++created_tab_contents_count_; } +// Subclass of TestNavigationObserver that saves ChromeNavigationUIData. +class TestNavigationUIDataObserver : public content::TestNavigationObserver { + public: + // Creates an observer that watches navigations to |target_url| on + // existing and newly added WebContents. + explicit TestNavigationUIDataObserver(const GURL& target_url) + : content::TestNavigationObserver(target_url) { + WatchExistingWebContents(); + StartWatchingNewWebContents(); + } + + const ChromeNavigationUIData* last_navigation_ui_data() const { + return static_cast<ChromeNavigationUIData*>(last_navigation_ui_data_.get()); + } + + private: + void OnDidFinishNavigation( + content::NavigationHandle* navigation_handle) override { + last_navigation_ui_data_ = + navigation_handle->GetNavigationUIData()->Clone(); + content::TestNavigationObserver::OnDidFinishNavigation(navigation_handle); + } + + std::unique_ptr<content::NavigationUIData> last_navigation_ui_data_ = nullptr; +}; + Browser* BrowserNavigatorTest::NavigateHelper( const GURL& url, Browser* browser, @@ -1667,4 +1696,79 @@ webui_rvh->GetMainFrame()->GetEnabledBindings()); } +// Test that main frame navigations generate a NavigationUIData with the +// correct disposition. +IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, MainFrameNavigationUIData) { + ASSERT_TRUE(embedded_test_server()->Start()); + + { + const GURL url = embedded_test_server()->GetURL("/title1.html"); + TestNavigationUIDataObserver observer(url); + + NavigateParams params(MakeNavigateParams()); + params.url = url; + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + ui_test_utils::NavigateToURL(¶ms); + observer.WaitForNavigationFinished(); + + EXPECT_EQ(WindowOpenDisposition::NEW_FOREGROUND_TAB, + observer.last_navigation_ui_data()->window_open_disposition()); + } + + { + const GURL url = embedded_test_server()->GetURL("/title2.html"); + TestNavigationUIDataObserver observer(url); + + NavigateParams params(MakeNavigateParams()); + params.url = url; + params.disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB; + ui_test_utils::NavigateToURL(¶ms); + observer.WaitForNavigationFinished(); + + EXPECT_EQ(WindowOpenDisposition::NEW_BACKGROUND_TAB, + observer.last_navigation_ui_data()->window_open_disposition()); + } +} + +// Test that subframe navigations generate a NavigationUIData with no +// disposition. +IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, SubFrameNavigationUIData) { + ASSERT_TRUE(embedded_test_server()->Start()); + + content::WebContents* tab = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Load page with iframe. + const GURL url1 = embedded_test_server()->GetURL("/iframe.html"); + ui_test_utils::NavigateToURL(browser(), url1); + + // Retrieve the iframe. + const auto all_frames = tab->GetAllFrames(); + const content::RenderFrameHost* main_frame = tab->GetMainFrame(); + DCHECK_EQ(2u, all_frames.size()); + auto it = std::find_if(all_frames.begin(), all_frames.end(), + [main_frame](content::RenderFrameHost* frame) { + return main_frame != frame; + }); + DCHECK(it != all_frames.end()); + content::RenderFrameHost* iframe = *it; + + // Navigate the iframe with a disposition. + NavigateParams params(browser(), + embedded_test_server()->GetURL("/simple.html"), + ui::PAGE_TRANSITION_LINK); + params.frame_tree_node_id = iframe->GetFrameTreeNodeId(); + params.disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB; + + TestNavigationUIDataObserver observer( + embedded_test_server()->GetURL("/simple.html")); + ui_test_utils::NavigateToURL(¶ms); + observer.WaitForNavigationFinished(); + + // The disposition passed to NavigateToURL should be ignored for sub frame + // navigations. + EXPECT_EQ(WindowOpenDisposition::CURRENT_TAB, + observer.last_navigation_ui_data()->window_open_disposition()); +} + } // namespace
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 54481c0..59ff064 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -2033,7 +2033,7 @@ // TODO(erikchen): Fullscreen modes should stack. Should be able to exit // Immersive Fullscreen and still be in AppKit Fullscreen. if ([self isInAppKitFullscreen]) - [self exitAppKitFullscreen]; + [self exitAppKitFullscreenAsync:NO]; if ([self isInImmersiveFullscreen]) [self exitImmersiveFullscreen]; }
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.h b/chrome/browser/ui/cocoa/browser_window_controller_private.h index f6815221..2fbf7252 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.h +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.h
@@ -114,10 +114,12 @@ // The distance from the toolbar bottom to the anchor point for InfoBars. - (NSInteger)infoBarAnchorPointY; -// Toggles the AppKit Fullscreen API. By default, doing so enters Canonical -// Fullscreen. +// Enter fullscreen by toggling the AppKit Fullscreen API. - (void)enterAppKitFullscreen; -- (void)exitAppKitFullscreen; + +// Exit fullscreen by toggling the AppKit Fullscreen API. If |async| is true, +// call -toggleFullscreen: asynchronously. +- (void)exitAppKitFullscreenAsync:(BOOL)async; // Returns where the fullscreen button should be positioned in the window. // Returns NSZeroRect if there is no fullscreen button (if currently in
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm index bedc4ae..312fc85 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -658,7 +658,13 @@ if (shouldExitAfterEnteringFullscreen_) { shouldExitAfterEnteringFullscreen_ = NO; - [self exitAppKitFullscreen]; + + // At 10.13, -windowDidEnteredFullscreen: is called before the AppKit + // fullscreen transition is complete. This causes AppKit to emit "not in + // fullscreen state" and ignore the call when we try to toggle fullscreen + // in the same runloop that entered it. To handle this case, invoke + // -toggleFullscreen: asynchronously. + [self exitAppKitFullscreenAsync:!base::mac::IsAtMostOS10_12()]; } // In macOS 10.12 and earlier, the web content's NSTrackingInVisibleRect @@ -867,7 +873,7 @@ [[self window] toggleFullScreen:nil]; } -- (void)exitAppKitFullscreen { +- (void)exitAppKitFullscreenAsync:(BOOL)async { // If we're in the process of entering fullscreen, toggleSystemFullscreen // will get ignored. Set |shouldExitAfterEnteringFullscreen_| to true so // the browser will exit fullscreen immediately after it enters it. @@ -876,7 +882,13 @@ return; } - [[self window] toggleFullScreen:nil]; + if (async) { + [[self window] performSelector:@selector(toggleFullScreen:) + withObject:nil + afterDelay:0]; + } else { + [[self window] toggleFullScreen:nil]; + } } - (NSRect)fullscreenButtonFrame {
diff --git a/chrome/browser/ui/extensions/extension_enable_flow.cc b/chrome/browser/ui/extensions/extension_enable_flow.cc index 87545dad..711d8a7 100644 --- a/chrome/browser/ui/extensions/extension_enable_flow.cc +++ b/chrome/browser/ui/extensions/extension_enable_flow.cc
@@ -12,13 +12,16 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h" -#include "chrome/browser/ui/user_manager.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" +#if !defined(OS_CHROMEOS) +#include "chrome/browser/ui/user_manager.h" +#endif // !defined(OS_CHROMEOS) + using extensions::Extension; ExtensionEnableFlow::ExtensionEnableFlow(Profile* profile, @@ -101,8 +104,10 @@ } if (profiles::IsProfileLocked(profile_->GetPath())) { +#if !defined(OS_CHROMEOS) UserManager::Show(base::FilePath(), profiles::USER_MANAGER_SELECT_PROFILE_APP_LAUNCHER); +#endif // !defined(OS_CHROMEOS) return; }
diff --git a/chrome/browser/ui/sad_tab.cc b/chrome/browser/ui/sad_tab.cc index ed7b484..2ebd746 100644 --- a/chrome/browser/ui/sad_tab.cc +++ b/chrome/browser/ui/sad_tab.cc
@@ -195,7 +195,10 @@ } void SadTab::RecordFirstPaint() { +#if !defined(OS_MACOSX) + // This DCHECK is causing tests on Mac-10.9 to flake. https://crbug.com/810416 DCHECK(!recorded_paint_); +#endif recorded_paint_ = true; switch (kind_) {
diff --git a/chrome/browser/ui/sad_tab.h b/chrome/browser/ui/sad_tab.h index 0a95dc62..58cbd1f 100644 --- a/chrome/browser/ui/sad_tab.h +++ b/chrome/browser/ui/sad_tab.h
@@ -37,11 +37,6 @@ virtual ~SadTab() {} - // Called when the sad tab needs to be reinstalled in its window, - // for example because an inactive tab was activated, or because a tab was - // dragged to a new browser window. - virtual void ReinstallInWebView() {} - // These functions return resource string IDs for UI text. They may be // different for each sad tab. (Right now, the first sad tab in a session // suggests reloading and subsequent ones suggest sending feedback.) @@ -65,8 +60,6 @@ protected: SadTab(content::WebContents* web_contents, SadTabKind kind); - content::WebContents* web_contents() const { return web_contents_; } - private: content::WebContents* web_contents_; SadTabKind kind_;
diff --git a/chrome/browser/ui/sad_tab_helper.cc b/chrome/browser/ui/sad_tab_helper.cc index 2fdb9f8a..ed0041b 100644 --- a/chrome/browser/ui/sad_tab_helper.cc +++ b/chrome/browser/ui/sad_tab_helper.cc
@@ -39,11 +39,6 @@ : content::WebContentsObserver(web_contents) { } -void SadTabHelper::ReinstallInWebView() { - if (sad_tab_) - sad_tab_->ReinstallInWebView(); -} - void SadTabHelper::RenderViewReady() { sad_tab_.reset(); }
diff --git a/chrome/browser/ui/sad_tab_helper.h b/chrome/browser/ui/sad_tab_helper.h index 5f11a82..a3461d9 100644 --- a/chrome/browser/ui/sad_tab_helper.h +++ b/chrome/browser/ui/sad_tab_helper.h
@@ -22,11 +22,6 @@ SadTab* sad_tab() { return sad_tab_.get(); } - // Called when the sad tab needs to be reinstalled in the WebView, - // for example because a tab was activated, or because a tab was - // dragged to a new browser window. - void ReinstallInWebView(); - private: friend class content::WebContentsUserData<SadTabHelper>;
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 2fae8c1..bca1302c 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -47,7 +47,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/startup/startup_browser_creator_impl.h" -#include "chrome/browser/ui/user_manager.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/features.h" @@ -78,6 +77,8 @@ #include "chromeos/chromeos_switches.h" #include "chromeos/cryptohome/cryptohome_parameters.h" #include "components/user_manager/user_manager.h" +#else +#include "chrome/browser/ui/user_manager.h" #endif #if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) @@ -272,11 +273,13 @@ } void ShowUserManagerOnStartup(const base::CommandLine& command_line) { +#if !defined(OS_CHROMEOS) profiles::UserManagerAction action = command_line.HasSwitch(switches::kShowAppList) ? profiles::USER_MANAGER_SELECT_PROFILE_APP_LAUNCHER : profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION; UserManager::Show(base::FilePath(), action); +#endif // !defined(OS_CHROMEOS) } } // namespace
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 2f87fe4f..c5e81e8 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -54,7 +54,6 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window_state.h" #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" -#include "chrome/browser/ui/sad_tab_helper.h" #include "chrome/browser/ui/sync/bubble_sync_promo_delegate.h" #include "chrome/browser/ui/tabs/tab_menu_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -788,10 +787,6 @@ if (change_tab_contents) { web_contents_close_handler_->ActiveTabChanged(); contents_web_view_->SetWebContents(new_contents); - SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(new_contents); - if (sad_tab_helper) - sad_tab_helper->ReinstallInWebView(); - // The second layout update should be no-op. It will just set the // DevTools WebContents. UpdateDevToolsForContents(new_contents, true); @@ -837,7 +832,7 @@ gfx::Size BrowserView::GetContentsSize() const { DCHECK(initialized_); - return contents_web_view_->size(); + return GetTabContentsContainerView()->size(); } bool BrowserView::IsMaximized() const { @@ -1437,6 +1432,10 @@ return toolbar_ ? toolbar_->location_bar() : nullptr; } +views::View* BrowserView::GetTabContentsContainerView() const { + return contents_web_view_; +} + /////////////////////////////////////////////////////////////////////////////// // BrowserView, TabStripModelObserver implementation: @@ -1896,7 +1895,7 @@ panes->push_back(infobar_container_); if (download_shelf_.get()) panes->push_back(download_shelf_.get()); - panes->push_back(contents_web_view_); + panes->push_back(GetTabContentsContainerView()); if (devtools_web_view_->visible()) panes->push_back(devtools_web_view_); }
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index ddcf79b2..4586e2d 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -198,9 +198,6 @@ return exclusive_access_bubble_.get(); } - // Accessor for the contents WebView. - views::WebView* contents_web_view() { return contents_web_view_; } - // Returns true if various window components are visible. bool IsTabStripVisible() const; @@ -385,6 +382,7 @@ BookmarkBarView* GetBookmarkBarView() const; LocationBarView* GetLocationBarView() const; + views::View* GetTabContentsContainerView() const; // Overridden from TabStripModelObserver: void TabInsertedAt(TabStripModel* tab_strip_model, @@ -488,6 +486,7 @@ // Testing interface: views::View* GetContentsContainerForTest() { return contents_container_; } + views::WebView* GetContentsWebViewForTest() { return contents_web_view_; } views::WebView* GetDevToolsWebViewForTest() { return devtools_web_view_; } // Called by BrowserFrame during theme changes.
diff --git a/chrome/browser/ui/views/frame/browser_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_view_browsertest.cc index 1253eb7..3ca1592 100644 --- a/chrome/browser/ui/views/frame/browser_view_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
@@ -38,7 +38,7 @@ } views::WebView* contents_web_view() { - return browser_view()->contents_web_view(); + return browser_view()->GetContentsWebViewForTest(); } void OpenDevToolsWindow(bool docked) {
diff --git a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc index ae7bc9d..afb9a71d 100644 --- a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc +++ b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
@@ -72,7 +72,7 @@ ASSERT_TRUE(widget2); const views::FocusManager* focus_manager2 = widget2->GetFocusManager(); ASSERT_TRUE(focus_manager2); - EXPECT_EQ(browser_view2->contents_web_view(), + EXPECT_EQ(browser_view2->GetTabContentsContainerView(), focus_manager2->GetFocusedView()); // Switch to the 1st browser window, focus should still be on the location @@ -86,7 +86,7 @@ views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); ASSERT_TRUE(widget); EXPECT_EQ(nullptr, widget->GetFocusManager()->GetFocusedView()); - EXPECT_EQ(browser_view2->contents_web_view(), + EXPECT_EQ(browser_view2->GetTabContentsContainerView(), focus_manager2->GetFocusedView()); // Close the 2nd browser to avoid a DCHECK().
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc index de56294..b91752ac 100644 --- a/chrome/browser/ui/views/frame/browser_view_unittest.cc +++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -83,7 +83,8 @@ ToolbarView* toolbar = browser_view()->toolbar(); views::View* contents_container = browser_view()->GetContentsContainerForTest(); - views::WebView* contents_web_view = browser_view()->contents_web_view(); + views::WebView* contents_web_view = + browser_view()->GetContentsWebViewForTest(); views::WebView* devtools_web_view = browser_view()->GetDevToolsWebViewForTest();
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc index b1f1765..420a7a08 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
@@ -89,7 +89,8 @@ IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshHostedAppBrowserTest, Layout) { TabStrip* tabstrip = browser_view()->tabstrip(); ToolbarView* toolbar = browser_view()->toolbar(); - views::WebView* contents_web_view = browser_view()->contents_web_view(); + views::WebView* contents_web_view = + browser_view()->GetContentsWebViewForTest(); views::View* top_container = browser_view()->top_container(); // Immersive fullscreen starts out disabled.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc index 5880a552..3d68da1 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -72,7 +72,7 @@ // Set whether the browser is in tab fullscreen. void SetTabFullscreen(bool tab_fullscreen) { content::WebContents* web_contents = - browser_view()->contents_web_view()->GetWebContents(); + browser_view()->GetContentsWebViewForTest()->GetWebContents(); std::unique_ptr<FullscreenNotificationObserver> waiter( new FullscreenNotificationObserver()); if (tab_fullscreen) { @@ -120,7 +120,8 @@ TabStrip* tabstrip = browser_view()->tabstrip(); ToolbarView* toolbar = browser_view()->toolbar(); - views::WebView* contents_web_view = browser_view()->contents_web_view(); + views::WebView* contents_web_view = + browser_view()->GetContentsWebViewForTest(); // Immersive fullscreen starts out disabled. ASSERT_FALSE(browser_view()->GetWidget()->IsFullscreen());
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 9b605a7..62d1fa3 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -187,7 +187,7 @@ // Initialize the Omnibox view. omnibox_view_ = new OmniboxViewViews( this, std::make_unique<ChromeOmniboxClient>(this, profile()), - command_updater(), is_popup_mode_, this, font_list); + is_popup_mode_, this, font_list); omnibox_view_->Init(); AddChildView(omnibox_view_);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index a29f871e..bc04106 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -115,7 +115,6 @@ OmniboxViewViews::OmniboxViewViews(OmniboxEditController* controller, std::unique_ptr<OmniboxClient> client, - CommandUpdater* command_updater, bool popup_window_mode, LocationBarView* location_bar, const gfx::FontList& font_list)
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index 8b49fe86..a36165a 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -28,7 +28,6 @@ #include "ui/base/ime/chromeos/input_method_manager.h" #endif -class CommandUpdater; class LocationBarView; class OmniboxClient; class OmniboxPopupContentsView; @@ -60,7 +59,6 @@ OmniboxViewViews(OmniboxEditController* controller, std::unique_ptr<OmniboxClient> client, - CommandUpdater* command_updater, bool popup_window_mode, LocationBarView* location_bar, const gfx::FontList& font_list);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc index f5a706f3..935b17e 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -51,8 +51,7 @@ }; TestingOmniboxView(OmniboxEditController* controller, - std::unique_ptr<OmniboxClient> client, - CommandUpdater* command_updater); + std::unique_ptr<OmniboxClient> client); static BaseTextEmphasis to_base_text_emphasis(bool emphasize) { return emphasize ? EMPHASIZED : DEEMPHASIZED; @@ -100,11 +99,9 @@ }; TestingOmniboxView::TestingOmniboxView(OmniboxEditController* controller, - std::unique_ptr<OmniboxClient> client, - CommandUpdater* command_updater) + std::unique_ptr<OmniboxClient> client) : OmniboxViewViews(controller, std::move(client), - command_updater, false, nullptr, gfx::FontList()) {} @@ -246,10 +243,8 @@ AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse( &profile_, &AutocompleteClassifierFactory::BuildInstanceFor); omnibox_view_ = std::make_unique<TestingOmniboxView>( - &omnibox_edit_controller_, - std::make_unique<ChromeOmniboxClient>(&omnibox_edit_controller_, - &profile_), - &command_updater_); + &omnibox_edit_controller_, std::make_unique<ChromeOmniboxClient>( + &omnibox_edit_controller_, &profile_)); test_api_ = std::make_unique<views::TextfieldTestApi>(omnibox_view_.get()); omnibox_view_->Init(); }
diff --git a/chrome/browser/ui/views/sad_tab_view.cc b/chrome/browser/ui/views/sad_tab_view.cc index 9b9ebcf..ccfb5436 100644 --- a/chrome/browser/ui/views/sad_tab_view.cc +++ b/chrome/browser/ui/views/sad_tab_view.cc
@@ -10,27 +10,22 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/harmony/bulleted_label_list_view.h" #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views_mode_controller.h" #include "content/public/browser/web_contents.h" -#include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/native_theme/common_theme.h" #include "ui/native_theme/native_theme.h" -#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/background.h" #include "ui/views/controls/button/md_text_button.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/link.h" -#include "ui/views/controls/webview/webview.h" #include "ui/views/layout/grid_layout.h" #include "ui/views/widget/widget.h" @@ -53,16 +48,8 @@ } // namespace -// static -const char SadTabView::kViewClassName[] = "SadTabView"; - SadTabView::SadTabView(content::WebContents* web_contents, SadTabKind kind) : SadTab(web_contents, kind) { - // This view gets inserted as a child of a WebView, but we don't want the - // WebView to delete us if the WebView gets deleted before the SadTabHelper - // does. - set_owned_by_client(); - SetBackground(views::CreateThemedSolidBackground( this, ui::NativeTheme::kColorId_DialogBackground)); @@ -133,46 +120,29 @@ layout->AddPaddingRow(2, provider->GetDistanceMetric( views::DISTANCE_UNRELATED_CONTROL_VERTICAL)); - AttachToWebView(); + views::Widget::InitParams sad_tab_params( + views::Widget::InitParams::TYPE_CONTROL); - // Make the accessibility role of this view an alert dialog, and - // put focus on the action button. This causes screen readers to - // immediately announce the text of this view. - GetViewAccessibility().OverrideRole(ax::mojom::Role::kDialog); - action_button_->RequestFocus(); + // It is not possible to create a native_widget_win that has no parent in + // and later re-parent it. + // TODO(avi): This is a cheat. Can this be made cleaner? + sad_tab_params.parent = web_contents->GetNativeView(); + + set_owned_by_client(); + + views::Widget* sad_tab = new views::Widget; + sad_tab->Init(sad_tab_params); + sad_tab->SetContentsView(this); + + views::Widget::ReparentNativeView(sad_tab->GetNativeView(), + web_contents->GetNativeView()); + gfx::Rect bounds = web_contents->GetContainerBounds(); + sad_tab->SetBounds(gfx::Rect(bounds.size())); } SadTabView::~SadTabView() { - if (owner_) - owner_->SetCrashedOverlayView(nullptr); -} - -void SadTabView::ReinstallInWebView() { - if (owner_) { - owner_->SetCrashedOverlayView(nullptr); - owner_ = nullptr; - } - AttachToWebView(); -} - -void SadTabView::AttachToWebView() { - Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); - // This can be null during prefetch. - if (!browser) - return; - - // In unit tests, browser->window() might not be a real BrowserView. - if (!browser->window()->GetNativeWindow()) - return; - - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); - DCHECK(browser_view); - - views::WebView* web_view = browser_view->contents_web_view(); - if (web_view->GetWebContents() == web_contents()) { - owner_ = web_view; - owner_->SetCrashedOverlayView(this); - } + if (GetWidget()) + GetWidget()->Close(); } void SadTabView::LinkClicked(views::Link* source, int event_flags) { @@ -197,10 +167,6 @@ View::Layout(); } -const char* SadTabView::GetClassName() const { - return kViewClassName; -} - void SadTabView::OnPaint(gfx::Canvas* canvas) { if (!painted_) { RecordFirstPaint(); @@ -209,10 +175,6 @@ View::OnPaint(canvas); } -void SadTabView::RemovedFromWidget() { - owner_ = nullptr; -} - SadTab* SadTab::Create(content::WebContents* web_contents, SadTabKind kind) { #if defined(OS_MACOSX)
diff --git a/chrome/browser/ui/views/sad_tab_view.h b/chrome/browser/ui/views/sad_tab_view.h index 54c2794e..7a398eb 100644 --- a/chrome/browser/ui/views/sad_tab_view.h +++ b/chrome/browser/ui/views/sad_tab_view.h
@@ -19,11 +19,6 @@ namespace views { class Label; class LabelButton; -class WebView; -} // namespace views - -namespace test { -class SadTabViewTestApi; } /////////////////////////////////////////////////////////////////////////////// @@ -39,17 +34,11 @@ public views::LinkListener, public views::ButtonListener { public: - static const char kViewClassName[]; - SadTabView(content::WebContents* web_contents, SadTabKind kind); ~SadTabView() override; - // Overridden from SadTab: - void ReinstallInWebView() override; - // Overridden from views::View: void Layout() override; - const char* GetClassName() const override; // Overridden from views::LinkListener: void LinkClicked(views::Link* source, int event_flags) override; @@ -60,22 +49,14 @@ protected: // Overridden from views::View: void OnPaint(gfx::Canvas* canvas) override; - void RemovedFromWidget() override; private: - friend class test::SadTabViewTestApi; - - // Set this View as the crashed overlay view for the WebView associated - // with this object's WebContents. - void AttachToWebView(); - bool painted_ = false; views::Label* message_; std::vector<views::Label*> bullet_labels_; views::Link* help_link_; views::LabelButton* action_button_; views::Label* title_; - views::WebView* owner_ = nullptr; DISALLOW_COPY_AND_ASSIGN(SadTabView); };
diff --git a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc deleted file mode 100644 index 71e9a1b..0000000 --- a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc +++ /dev/null
@@ -1,204 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/sad_tab_view.h" - -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/sad_tab.h" -#include "chrome/browser/ui/sad_tab_helper.h" -#include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/toolbar/toolbar_view.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/interactive_test_utils.h" -#include "chrome/test/base/ui_test_utils.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/common/result_codes.h" -#include "content/public/test/browser_test_utils.h" -#include "ui/views/controls/button/blue_button.h" -#include "ui/views/controls/button/label_button.h" -#include "ui/views/widget/widget.h" - -namespace test { - -// A friend of SadTabView that's able to call RecordFirstPaint. -class SadTabViewTestApi { - public: - static void RecordFirstPaintForTesting(SadTabView* sad_tab_view) { - if (!sad_tab_view->painted_) { - sad_tab_view->RecordFirstPaint(); - sad_tab_view->painted_ = true; - } - } - - private: - DISALLOW_COPY_AND_ASSIGN(SadTabViewTestApi); -}; - -} // namespace test - -class SadTabViewInteractiveUITest : public InProcessBrowserTest { - public: - SadTabViewInteractiveUITest() {} - - protected: - void KillRendererForActiveWebContentsSync() { - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - content::RenderProcessHost* process = - web_contents->GetMainFrame()->GetProcess(); - content::RenderProcessHostWatcher crash_observer( - process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - process->Shutdown(content::RESULT_CODE_KILLED, false); - crash_observer.Wait(); - } - - void PressTab() { - ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, false, - false, false, false)); - } - - void PressShiftTab() { - ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, false, - true, false, false)); - } - - void PressSpacebar() { - ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_SPACE, - false, false, false, false)); - } - - views::FocusManager* GetFocusManager() { - BrowserView* browser_view = - BrowserView::GetBrowserViewForBrowser(browser()); - return browser_view->GetWidget()->GetFocusManager(); - } - - views::View* GetFocusedView() { return GetFocusManager()->GetFocusedView(); } - - const char* ActionButtonClassName() { -#if defined(OS_CHROMEOS) - return views::BlueButton::kViewClassName; -#else - return views::LabelButton::kViewClassName; -#endif - } - - bool IsFocusedViewInsideViewClass(const char* view_class) { - views::View* view = GetFocusedView(); - while (view) { - if (view->GetClassName() == view_class) - return true; - view = view->parent(); - } - return false; - } - - bool IsFocusedViewInsideSadTab() { - return IsFocusedViewInsideViewClass(SadTabView::kViewClassName); - } - - bool IsFocusedViewInsideBrowserToolbar() { - return IsFocusedViewInsideViewClass(ToolbarView::kViewClassName); - } - - bool IsFocusedViewOnActionButtonInSadTab() { - return IsFocusedViewInsideViewClass(SadTabView::kViewClassName) && - IsFocusedViewInsideViewClass(ActionButtonClassName()); - } - - void ClickOnActionButtonInSadTab() { - TabStripModel* tab_strip_model = browser()->tab_strip_model(); - content::WebContents* web_contents = - tab_strip_model->GetActiveWebContents(); - while (!IsFocusedViewOnActionButtonInSadTab()) - PressTab(); - - // SadTab has a DCHECK that it's been painted at least once - // before the action button can be pressed, bypass that. - SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(web_contents); - SadTabView* sad_tab_view = - static_cast<SadTabView*>(sad_tab_helper->sad_tab()); - test::SadTabViewTestApi::RecordFirstPaintForTesting(sad_tab_view); - PressSpacebar(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(SadTabViewInteractiveUITest); -}; - -IN_PROC_BROWSER_TEST_F(SadTabViewInteractiveUITest, - SadTabKeyboardAccessibility) { - ASSERT_TRUE(embedded_test_server()->Start()); - GURL url(embedded_test_server()->GetURL("/links.html")); - ui_test_utils::NavigateToURL(browser(), url); - - // Start with focus in the location bar. - chrome::FocusLocationBar(browser()); - ASSERT_FALSE(IsFocusedViewInsideSadTab()); - ASSERT_TRUE(IsFocusedViewInsideBrowserToolbar()); - - // Kill the renderer process, resulting in a sad tab. - KillRendererForActiveWebContentsSync(); - - // Focus should now be on a label button inside the sad tab. - ASSERT_STREQ(GetFocusedView()->GetClassName(), ActionButtonClassName()); - ASSERT_TRUE(IsFocusedViewInsideSadTab()); - ASSERT_FALSE(IsFocusedViewInsideBrowserToolbar()); - - // Pressing the Tab key should cycle focus back to the toolbar. - PressTab(); - ASSERT_FALSE(IsFocusedViewInsideSadTab()); - ASSERT_TRUE(IsFocusedViewInsideBrowserToolbar()); - - // Keep pressing the Tab key and make sure we make it back to the sad tab. - while (!IsFocusedViewInsideSadTab()) - PressTab(); - ASSERT_FALSE(IsFocusedViewInsideBrowserToolbar()); - - // Press Shift-Tab and ensure we end up back in the toolbar. - PressShiftTab(); - ASSERT_FALSE(IsFocusedViewInsideSadTab()); - ASSERT_TRUE(IsFocusedViewInsideBrowserToolbar()); -} - -IN_PROC_BROWSER_TEST_F(SadTabViewInteractiveUITest, ReloadMultipleSadTabs) { - ASSERT_TRUE(embedded_test_server()->Start()); - GURL url(embedded_test_server()->GetURL("/links.html")); - ui_test_utils::NavigateToURL(browser(), url); - - // Kill the renderer process, resulting in a sad tab. - KillRendererForActiveWebContentsSync(); - - // Create a second tab, navigate to a second url. - chrome::NewTab(browser()); - GURL url2(embedded_test_server()->GetURL("/simple.html")); - ui_test_utils::NavigateToURL(browser(), url2); - - // Kill that one too. - KillRendererForActiveWebContentsSync(); - - // Switch back to the first tab. - TabStripModel* tab_strip_model = browser()->tab_strip_model(); - EXPECT_EQ(1, tab_strip_model->active_index()); - tab_strip_model->ActivateTabAt(0, true); - EXPECT_EQ(0, tab_strip_model->active_index()); - content::WebContents* web_contents = tab_strip_model->GetActiveWebContents(); - EXPECT_TRUE(web_contents->IsCrashed()); - - ClickOnActionButtonInSadTab(); - - // Ensure the first WebContents reloads. - content::WaitForLoadStop(web_contents); - EXPECT_FALSE(web_contents->IsCrashed()); - - // Switch to the second tab, reload it too. - tab_strip_model->ActivateTabAt(1, true); - web_contents = tab_strip_model->GetActiveWebContents(); - EXPECT_TRUE(web_contents->IsCrashed()); - ClickOnActionButtonInSadTab(); - content::WaitForLoadStop(web_contents); - EXPECT_FALSE(web_contents->IsCrashed()); -}
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc index 3ee3094..914b32e3 100644 --- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc +++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
@@ -97,6 +97,15 @@ params)); } +void ChromeWebContentsViewDelegateViews::SizeChanged(const gfx::Size& size) { + SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(web_contents_); + if (!sad_tab_helper) + return; + SadTabView* sad_tab = static_cast<SadTabView*>(sad_tab_helper->sad_tab()); + if (sad_tab) + sad_tab->GetWidget()->SetBounds(gfx::Rect(size)); +} + content::WebContentsViewDelegate* CreateWebContentsViewDelegate( content::WebContents* web_contents) { return new ChromeWebContentsViewDelegateViews(web_contents);
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h index 684850c..1a9e68f 100644 --- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h +++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h
@@ -41,6 +41,7 @@ bool TakeFocus(bool reverse) override; void ShowContextMenu(content::RenderFrameHost* render_frame_host, const content::ContextMenuParams& params) override; + void SizeChanged(const gfx::Size& size) override; // Overridden from ContextMenuDelegate. std::unique_ptr<RenderViewContextMenuBase> BuildMenu(
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h index e5238d2..c6d75a22 100644 --- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h +++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.h
@@ -23,7 +23,6 @@ void ResetStoredFocus() override; bool Focus() override; bool TakeFocus(bool reverse) override; - void SizeChanged(const gfx::Size& size) override; private: // Used to handle focus management.
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 2d0c9af..e3ce7c2 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/sad_tab_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -916,12 +915,6 @@ add_types |= TabStripModel::ADD_PINNED; GetModel(attached_tabstrip_)->InsertWebContentsAt( index + i, drag_data_[i].contents, add_types); - - // If a sad tab is showing, the SadTabView needs to be updated. - SadTabHelper* sad_tab_helper = - SadTabHelper::FromWebContents(drag_data_[i].contents); - if (sad_tab_helper) - sad_tab_helper->ReinstallInWebView(); } tabs = GetTabsMatchingDraggedContents(attached_tabstrip_); @@ -980,6 +973,7 @@ // Hide the tab so that the user doesn't see it animate closed. drag_data_[i].attached_tab->SetVisible(false); drag_data_[i].attached_tab->set_detached(); + attached_model->DetachWebContentsAt(index); // Detaching may end up deleting the tab, drop references to it.
diff --git a/chrome/browser/ui/views/task_manager_view.cc b/chrome/browser/ui/views/task_manager_view.cc index 31c7cd8..febfeaf 100644 --- a/chrome/browser/ui/views/task_manager_view.cc +++ b/chrome/browser/ui/views/task_manager_view.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/task_manager/task_manager_columns.h" -#include "chrome/browser/ui/user_manager.h" #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.cc b/chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.cc index 4fd2ef91..495bd41c 100644 --- a/chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.cc
@@ -84,10 +84,16 @@ AddBluetoothStrings(source); source->AddLocalizedString("title", IDS_SETTINGS_BLUETOOTH_PAIR_DEVICE_TITLE); source->SetJsonPath("strings.js"); +#if BUILDFLAG(OPTIMIZE_WEBUI) + source->UseGzip(); + source->SetDefaultResource(IDR_BLUETOOTH_PAIRING_DIALOG_VULCANIZED_HTML); + source->AddResourcePath("crisper.js", + IDR_BLUETOOTH_PAIRING_DIALOG_CRISPER_JS); +#else source->SetDefaultResource(IDR_BLUETOOTH_PAIRING_DIALOG_HTML); source->AddResourcePath("bluetooth_pairing_dialog.js", IDR_BLUETOOTH_PAIRING_DIALOG_JS); - +#endif content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source); }
diff --git a/chrome/browser/ui/webui/chromeos/internet_config_dialog.cc b/chrome/browser/ui/webui/chromeos/internet_config_dialog.cc index 2f559bed..0591f3b 100644 --- a/chrome/browser/ui/webui/chromeos/internet_config_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/internet_config_dialog.cc
@@ -113,9 +113,15 @@ AddInternetStrings(source); source->AddLocalizedString("title", IDS_SETTINGS_INTERNET_CONFIG); source->SetJsonPath("strings.js"); +#if BUILDFLAG(OPTIMIZE_WEBUI) + source->UseGzip(); + source->SetDefaultResource(IDR_INTERNET_CONFIG_DIALOG_VULCANIZED_HTML); + source->AddResourcePath("crisper.js", IDR_INTERNET_CONFIG_DIALOG_CRISPER_JS); +#else source->SetDefaultResource(IDR_INTERNET_CONFIG_DIALOG_HTML); source->AddResourcePath("internet_config_dialog.js", IDR_INTERNET_CONFIG_DIALOG_JS); +#endif content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source); }
diff --git a/chrome/browser/ui/webui/chromeos/internet_detail_dialog.cc b/chrome/browser/ui/webui/chromeos/internet_detail_dialog.cc index 327acb5..3f191280 100644 --- a/chrome/browser/ui/webui/chromeos/internet_detail_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/internet_detail_dialog.cc
@@ -113,10 +113,15 @@ AddInternetStrings(source); source->AddLocalizedString("title", IDS_SETTINGS_INTERNET_DETAIL); source->SetJsonPath("strings.js"); +#if BUILDFLAG(OPTIMIZE_WEBUI) + source->UseGzip(); + source->SetDefaultResource(IDR_INTERNET_DETAIL_DIALOG_VULCANIZED_HTML); + source->AddResourcePath("crisper.js", IDR_INTERNET_DETAIL_DIALOG_CRISPER_JS); +#else source->SetDefaultResource(IDR_INTERNET_DETAIL_DIALOG_HTML); source->AddResourcePath("internet_detail_dialog.js", IDR_INTERNET_DETAIL_DIALOG_JS); - +#endif content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source); }
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index 4c243a3..fb22a44 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -351,6 +351,16 @@ new_tab_guest_html_ = base::RefCountedString::TakeString(&full_html); } +// TODO(alancutter): Consider moving this utility function up somewhere where it +// can be shared with md_bookmarks_ui.cc. +// Ampersands are used by menus to determine which characters to use as shortcut +// keys. This functionality is not implemented for NTP. +static base::string16 GetLocalizedString(int message_id) { + base::string16 result = l10n_util::GetStringUTF16(message_id); + result.erase(std::remove(result.begin(), result.end(), '&'), result.end()); + return result; +} + void NTPResourceCache::CreateNewTabHTML() { // TODO(estade): these strings should be defined in their relevant handlers // (in GetLocalizedValues) and should have more legible names. @@ -361,57 +371,63 @@ load_time_data.SetString( "bookmarkbarattached", prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar) ? "true" : "false"); - load_time_data.SetString("title", - l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE)); + load_time_data.SetString("title", GetLocalizedString(IDS_NEW_TAB_TITLE)); load_time_data.SetString("webStoreTitle", - l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)); - load_time_data.SetString("webStoreTitleShort", - l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE_SHORT)); + GetLocalizedString(IDS_EXTENSION_WEB_STORE_TITLE)); + load_time_data.SetString( + "webStoreTitleShort", + GetLocalizedString(IDS_EXTENSION_WEB_STORE_TITLE_SHORT)); load_time_data.SetString("attributionintro", - l10n_util::GetStringUTF16(IDS_NEW_TAB_ATTRIBUTION_INTRO)); + GetLocalizedString(IDS_NEW_TAB_ATTRIBUTION_INTRO)); load_time_data.SetString("appuninstall", - l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL)); + GetLocalizedString(IDS_EXTENSIONS_UNINSTALL)); load_time_data.SetString("appoptions", - l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_OPTIONS)); + GetLocalizedString(IDS_NEW_TAB_APP_OPTIONS)); load_time_data.SetString("appdetails", - l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_DETAILS)); + GetLocalizedString(IDS_NEW_TAB_APP_DETAILS)); load_time_data.SetString("appinfodialog", - l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_SHOW_INFO)); + GetLocalizedString(IDS_APP_CONTEXT_MENU_SHOW_INFO)); load_time_data.SetString("appcreateshortcut", - l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_CREATE_SHORTCUT)); + GetLocalizedString(IDS_NEW_TAB_APP_CREATE_SHORTCUT)); load_time_data.SetString("appDefaultPageName", - l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME)); - load_time_data.SetString("applaunchtypepinned", - l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_PINNED)); - load_time_data.SetString("applaunchtyperegular", - l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_REGULAR)); - load_time_data.SetString("applaunchtypewindow", - l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW)); - load_time_data.SetString("applaunchtypefullscreen", - l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN)); - load_time_data.SetString("syncpromotext", - l10n_util::GetStringUTF16(IDS_SYNC_START_SYNC_BUTTON_LABEL)); + GetLocalizedString(IDS_APP_DEFAULT_PAGE_NAME)); + load_time_data.SetString( + "applaunchtypepinned", + GetLocalizedString(IDS_APP_CONTEXT_MENU_OPEN_PINNED)); + load_time_data.SetString( + "applaunchtyperegular", + GetLocalizedString(IDS_APP_CONTEXT_MENU_OPEN_REGULAR)); + load_time_data.SetString( + "applaunchtypewindow", + GetLocalizedString(IDS_APP_CONTEXT_MENU_OPEN_WINDOW)); + load_time_data.SetString( + "applaunchtypefullscreen", + GetLocalizedString(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN)); + load_time_data.SetString( + "syncpromotext", GetLocalizedString(IDS_SYNC_START_SYNC_BUTTON_LABEL)); load_time_data.SetString("syncLinkText", - l10n_util::GetStringUTF16(IDS_SYNC_ADVANCED_OPTIONS)); + GetLocalizedString(IDS_SYNC_ADVANCED_OPTIONS)); load_time_data.SetBoolean("shouldShowSyncLogin", AppLauncherLoginHandler::ShouldShow(profile_)); - load_time_data.SetString("learnMore", - l10n_util::GetStringUTF16(IDS_LEARN_MORE)); + load_time_data.SetString("learnMore", GetLocalizedString(IDS_LEARN_MORE)); const std::string& app_locale = g_browser_process->GetApplicationLocale(); load_time_data.SetString( "webStoreLink", google_util::AppendGoogleLocaleParam( extension_urls::GetWebstoreLaunchURL(), app_locale) .spec()); - load_time_data.SetString("appInstallHintText", - l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_INSTALL_HINT_LABEL)); - load_time_data.SetString("learn_more", - l10n_util::GetStringUTF16(IDS_LEARN_MORE)); - load_time_data.SetString("tile_grid_screenreader_accessible_description", - l10n_util::GetStringUTF16(IDS_NEW_TAB_TILE_GRID_ACCESSIBLE_DESCRIPTION)); - load_time_data.SetString("page_switcher_change_title", - l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_SWITCHER_CHANGE_TITLE)); - load_time_data.SetString("page_switcher_same_title", - l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_SWITCHER_SAME_TITLE)); + load_time_data.SetString( + "appInstallHintText", + GetLocalizedString(IDS_NEW_TAB_APP_INSTALL_HINT_LABEL)); + load_time_data.SetString("learn_more", GetLocalizedString(IDS_LEARN_MORE)); + load_time_data.SetString( + "tile_grid_screenreader_accessible_description", + GetLocalizedString(IDS_NEW_TAB_TILE_GRID_ACCESSIBLE_DESCRIPTION)); + load_time_data.SetString( + "page_switcher_change_title", + GetLocalizedString(IDS_NEW_TAB_PAGE_SWITCHER_CHANGE_TITLE)); + load_time_data.SetString( + "page_switcher_same_title", + GetLocalizedString(IDS_NEW_TAB_PAGE_SWITCHER_SAME_TITLE)); // On Mac OS X 10.7+, horizontal scrolling can be treated as a back or // forward gesture. Pass through a flag that indicates whether or not that // feature is enabled.
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 35b7e38..464f860 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -31,8 +31,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/singleton_tabs.h" -#include "chrome/browser/ui/user_manager.h" -#include "chrome/browser/ui/webui/profile_helper.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/common/chrome_switches.h" @@ -62,14 +60,15 @@ #if defined(OS_CHROMEOS) #include "components/signin/core/browser/signin_manager_base.h" #else +#include "chrome/browser/ui/user_manager.h" +#include "chrome/browser/ui/webui/profile_helper.h" #include "components/signin/core/browser/signin_manager.h" #endif #if BUILDFLAG(ENABLE_DICE_SUPPORT) -// TODO(scottchen): no longer need icon_util once we start loading real -// account pictures. -#include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "components/signin/core/browser/account_tracker_service.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/image/image.h" #endif using browser_sync::ProfileSyncService; @@ -462,6 +461,8 @@ std::vector<AccountInfo> accounts = signin_ui_util::GetAccountsForDicePromos(profile_); + AccountTrackerService* account_tracker = + AccountTrackerServiceFactory::GetForProfile(profile_); std::unique_ptr<base::ListValue> accounts_list(new base::ListValue); accounts_list->Reserve(accounts.size()); @@ -471,8 +472,13 @@ base::Value& acc = accounts_list->GetList().back(); acc.SetKey("email", base::Value(account.email)); acc.SetKey("fullName", base::Value(account.full_name)); - // TODO(scottchen): should return account.picture_url as encoded image. - acc.SetKey("image", base::Value(profiles::GetPlaceholderAvatarIconUrl())); + const gfx::Image& account_image = + account_tracker->GetAccountImage(account.account_id); + if (!account_image.IsEmpty()) { + acc.SetKey( + "avatarImage", + base::Value(webui::GetBitmapDataUrl(account_image.AsBitmap()))); + } } return accounts_list; @@ -650,8 +656,10 @@ } void PeopleHandler::HandleManageOtherPeople(const base::ListValue* /* args */) { +#if !defined(OS_CHROMEOS) UserManager::Show(base::FilePath(), profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); +#endif // !defined(OS_CHROMEOS) } void PeopleHandler::CloseSyncSetup() {
diff --git a/chrome/browser/ui/webui/settings/profile_info_handler.cc b/chrome/browser/ui/webui/settings/profile_info_handler.cc index 1883b6d..299d6fe 100644 --- a/chrome/browser/ui/webui/settings/profile_info_handler.cc +++ b/chrome/browser/ui/webui/settings/profile_info_handler.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_attributes_entry.h" -#include "chrome/browser/ui/user_manager.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/pref_names.h" #include "ui/base/webui/web_ui_util.h"
diff --git a/chrome/browser/ui/webui/signin/login_ui_service.cc b/chrome/browser/ui/webui/signin/login_ui_service.cc index 1e21d92..4ef22822 100644 --- a/chrome/browser/ui/webui/signin/login_ui_service.cc +++ b/chrome/browser/ui/webui/signin/login_ui_service.cc
@@ -11,12 +11,15 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" -#include "chrome/browser/ui/user_manager.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/common/url_constants.h" #include "components/signin/core/browser/profile_management_switches.h" #include "components/signin/core/browser/signin_header_helper.h" +#if !defined(OS_CHROMEOS) +#include "chrome/browser/ui/user_manager.h" +#endif // !defined(OS_CHROMEOS) + LoginUIService::LoginUIService(Profile* profile) #if !defined(OS_CHROMEOS) : profile_(profile)
diff --git a/chrome/browser/ui/webui/welcome_handler.cc b/chrome/browser/ui/webui/welcome_handler.cc index c764d29..d989be5 100644 --- a/chrome/browser/ui/webui/welcome_handler.cc +++ b/chrome/browser/ui/webui/welcome_handler.cc
@@ -23,12 +23,18 @@ login_ui_service_(LoginUIServiceFactory::GetForProfile(profile_)), result_(WelcomeResult::DEFAULT) { login_ui_service_->AddObserver(this); - base::RecordAction( - base::UserMetricsAction("Signin_Impression_FromStartPage")); } WelcomeHandler::~WelcomeHandler() { login_ui_service_->RemoveObserver(this); + + // We log that an impression occurred at destruct-time. This can't be done at + // construct-time on some platforms because this page is shown immediately + // after a new installation of Chrome and loads while the user is deciding + // whether or not to opt in to logging. + base::RecordAction( + base::UserMetricsAction("Signin_Impression_FromStartPage")); + UMA_HISTOGRAM_ENUMERATION("Welcome.SignInPromptResult", result_, WelcomeResult::WELCOME_RESULT_MAX); }
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc index ac68cbe..47f214f 100644 --- a/chrome/browser/vr/elements/ui_element_name.cc +++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -87,6 +87,7 @@ "kPermissionDialogBackplane", "kHostedUi", "kHostedUiBackplane", + "kHostedUiCloseButton", "kWebVrUrlToastTransientParent", "kWebVrUrlToast", "kExclusiveScreenToastTransientParent",
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h index cf3639d..37972ef 100644 --- a/chrome/browser/vr/elements/ui_element_name.h +++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -86,6 +86,7 @@ kPermissionDialogBackplane, kHostedUi, kHostedUiBackplane, + kHostedUiCloseButton, kWebVrUrlToastTransientParent, kWebVrUrlToast, kExclusiveScreenToastTransientParent,
diff --git a/chrome/browser/vr/test/mock_ui_browser_interface.h b/chrome/browser/vr/test/mock_ui_browser_interface.h index 3f1e36b..42114d7 100644 --- a/chrome/browser/vr/test/mock_ui_browser_interface.h +++ b/chrome/browser/vr/test/mock_ui_browser_interface.h
@@ -21,6 +21,7 @@ MOCK_METHOD1(Navigate, void(GURL gurl)); MOCK_METHOD0(NavigateBack, void()); MOCK_METHOD0(ExitCct, void()); + MOCK_METHOD0(CloseHostedDialog, void()); MOCK_METHOD1(OnUnsupportedMode, void(UiUnsupportedMode mode)); MOCK_METHOD2(OnExitVrPromptResult, void(ExitVrPromptChoice choice, UiUnsupportedMode reason));
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index d623613..3e226b3 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -473,6 +473,8 @@ } } +void VrTestContext::CloseHostedDialog() {} + void VrTestContext::OnExitVrPromptResult(vr::ExitVrPromptChoice choice, vr::UiUnsupportedMode reason) { if (reason == UiUnsupportedMode::kVoiceSearchNeedsRecordAudioOsPermission &&
diff --git a/chrome/browser/vr/testapp/vr_test_context.h b/chrome/browser/vr/testapp/vr_test_context.h index fa7ee0c..bbee184 100644 --- a/chrome/browser/vr/testapp/vr_test_context.h +++ b/chrome/browser/vr/testapp/vr_test_context.h
@@ -45,6 +45,7 @@ void ExitFullscreen() override; void NavigateBack() override; void ExitCct() override; + void CloseHostedDialog() override; void OnUnsupportedMode(vr::UiUnsupportedMode mode) override; void OnExitVrPromptResult(vr::ExitVrPromptChoice choice, vr::UiUnsupportedMode reason) override;
diff --git a/chrome/browser/vr/ui_browser_interface.h b/chrome/browser/vr/ui_browser_interface.h index 4fd99539..990cfb1 100644 --- a/chrome/browser/vr/ui_browser_interface.h +++ b/chrome/browser/vr/ui_browser_interface.h
@@ -24,6 +24,7 @@ virtual void Navigate(GURL gurl) = 0; virtual void NavigateBack() = 0; virtual void ExitCct() = 0; + virtual void CloseHostedDialog() = 0; virtual void OnUnsupportedMode(UiUnsupportedMode mode) = 0; virtual void OnExitVrPromptResult(ExitVrPromptChoice choice, UiUnsupportedMode reason) = 0;
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index a2a6ab9..1ad52d9 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -204,6 +204,8 @@ static constexpr float kHostedUiHeightRatio = 0.6f; static constexpr float kHostedUiWidthRatio = 0.6f; static constexpr float kHostedUiDepthOffset = 0.3f; +static constexpr float kHostedUiCloseButtonDiameter = 0.11f; +static constexpr float kHostedUiCloseButtonZOffsetHover = 0.05f; static constexpr float kScreenDimmerOpacity = 0.9f;
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index bf5a332..096cbb9e 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -589,6 +589,27 @@ } void UiSceneCreator::CreateHostedUi() { + base::RepeatingCallback<void()> click_handler = base::BindRepeating( + [](Model* model, UiBrowserInterface* browser) { + if (model->native_ui.hosted_ui_enabled) { + browser->CloseHostedDialog(); + } + }, + base::Unretained(model_), base::Unretained(browser_)); + auto close_button = + Create<DiscButton>(kHostedUiCloseButton, kPhaseForeground, click_handler, + vector_icons::kClose16Icon); + close_button->SetSize(kHostedUiCloseButtonDiameter, + kHostedUiCloseButtonDiameter); + close_button->set_hover_offset(kHostedUiCloseButtonZOffsetHover); + close_button->SetTranslate(-kHostedUiCloseButtonDiameter / 2, + -kHostedUiCloseButtonDiameter / 2, 0); + close_button->set_y_anchoring(TOP); + close_button->set_x_anchoring(RIGHT); + + VR_BIND_BUTTON_COLORS(model_, close_button.get(), &ColorScheme::button_colors, + &DiscButton::SetButtonColors); + auto backplane = std::make_unique<InvisibleHitTarget>(); backplane->SetDrawPhase(kPhaseForeground); backplane->SetName(kHostedUiBackplane); @@ -636,6 +657,7 @@ kContentWidth * kHostedUiWidthRatio * value); }, base::Unretained(hosted_ui.get())))); + hosted_ui->AddChild(std::move(close_button)); backplane->AddChild(std::move(hosted_ui)); scene_->AddUiElement(k2dBrowsingRoot, std::move(backplane)); }
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 23080734..4fa57b3 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -179,8 +179,6 @@ "ssl_insecure_content.h", "stack_sampling_configuration.cc", "stack_sampling_configuration.h", - "thread_profiler.cc", - "thread_profiler.h", "trace_event_args_whitelist.cc", "trace_event_args_whitelist.h", "tts_messages.h", @@ -281,10 +279,6 @@ "//url", ] - deps = [ - "//components/metrics:child_call_stacks", - ] - if (enable_plugins) { public_deps += [ "//ppapi/shared_impl" ] } @@ -437,7 +431,7 @@ } if (is_win) { - deps += [ + deps = [ "//chrome/common/win:eventlog_messages", "//chrome_elf:chrome_elf_main_include", "//components/crash/content/app:crash_export_thunk_include", @@ -491,7 +485,9 @@ } if (is_linux) { - deps += [ "//sandbox/linux:sandbox_services" ] + deps = [ + "//sandbox/linux:sandbox_services", + ] } if (enable_cdm_host_verification) {
diff --git a/chrome/common/DEPS b/chrome/common/DEPS index ac07516..283adc4 100644 --- a/chrome/common/DEPS +++ b/chrome/common/DEPS
@@ -19,9 +19,6 @@ "+components/favicon_base", "+components/flags_ui/flags_ui_switches.h", "+components/gcm_driver", - "+components/metrics/call_stack_profile_metrics_provider.h", - "+components/metrics/call_stack_profile_params.h", - "+components/metrics/child_call_stack_profile_collector.h", "+components/metrics/client_info.h", "+components/metrics/metrics_pref_names.h", "+components/nacl/common", @@ -49,7 +46,6 @@ "+rlz/features/features.h", "+sandbox/linux/services/credentials.h", "+services/network/public/cpp", - "+services/service_manager/public", "+services/service_manager/sandbox", "+third_party/boringssl/src/include", "+third_party/WebKit/public/platform/web_client_hints_types.mojom.h",
diff --git a/chrome/common/features.gni b/chrome/common/features.gni index 21a06a5..e80be25 100644 --- a/chrome/common/features.gni +++ b/chrome/common/features.gni
@@ -60,10 +60,7 @@ # Indicates if the build is using PGO. pgo_build = chrome_pgo_phase > 0 - # Optimize parts of Chrome's UI written with web technologies (HTML/CSS/JS) - # for runtime performance purposes. This does more work at compile time for - # speed benefits at runtime (so we skip in debug builds). - optimize_webui = !is_debug + # optimize_webui was moved to ui/base/ui_features.gni } # Use brlapi from brltty for braille display support.
diff --git a/chrome/common/thread_profiler.cc b/chrome/common/thread_profiler.cc deleted file mode 100644 index a436629..0000000 --- a/chrome/common/thread_profiler.cc +++ /dev/null
@@ -1,139 +0,0 @@ -// Copyright 2018 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/common/thread_profiler.h" - -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/lazy_instance.h" -#include "base/threading/platform_thread.h" -#include "base/threading/sequence_local_storage_slot.h" -#include "chrome/common/stack_sampling_configuration.h" -#include "components/metrics/call_stack_profile_metrics_provider.h" -#include "components/metrics/call_stack_profile_params.h" -#include "components/metrics/child_call_stack_profile_collector.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/service_names.mojom.h" -#include "services/service_manager/public/cpp/connector.h" - -namespace { - -// Only used by child processes. -base::LazyInstance<metrics::ChildCallStackProfileCollector>::Leaky - g_child_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER; - -// The profiler object is stored in a SequenceLocalStorageSlot on child threads -// to give it the same lifetime as the threads. -base::LazyInstance< - base::SequenceLocalStorageSlot<std::unique_ptr<ThreadProfiler>>>::Leaky - g_child_thread_profiler_sequence_local_storage = LAZY_INSTANCE_INITIALIZER; - -base::StackSamplingProfiler::SamplingParams GetSamplingParams() { - base::StackSamplingProfiler::SamplingParams params; - params.initial_delay = base::TimeDelta::FromMilliseconds(0); - params.bursts = 1; - params.samples_per_burst = 300; - params.sampling_interval = base::TimeDelta::FromMilliseconds(100); - return params; -} - -metrics::CallStackProfileParams::Process GetProcess() { - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - std::string process_type = - command_line->GetSwitchValueASCII(switches::kProcessType); - if (process_type.empty()) - return metrics::CallStackProfileParams::BROWSER_PROCESS; - if (process_type == switches::kRendererProcess) - return metrics::CallStackProfileParams::RENDERER_PROCESS; - if (process_type == switches::kGpuProcess) - return metrics::CallStackProfileParams::GPU_PROCESS; - if (process_type == switches::kUtilityProcess) - return metrics::CallStackProfileParams::UTILITY_PROCESS; - if (process_type == switches::kZygoteProcess) - return metrics::CallStackProfileParams::ZYGOTE_PROCESS; - if (process_type == switches::kPpapiPluginProcess) - return metrics::CallStackProfileParams::PPAPI_PLUGIN_PROCESS; - if (process_type == switches::kPpapiBrokerProcess) - return metrics::CallStackProfileParams::PPAPI_BROKER_PROCESS; - return metrics::CallStackProfileParams::UNKNOWN_PROCESS; -} - -} // namespace - -ThreadProfiler::~ThreadProfiler() {} - -// static -std::unique_ptr<ThreadProfiler> ThreadProfiler::CreateAndStartOnMainThread( - metrics::CallStackProfileParams::Thread thread) { - return std::unique_ptr<ThreadProfiler>(new ThreadProfiler(thread)); -} - -// static -void ThreadProfiler::StartOnChildThread( - metrics::CallStackProfileParams::Thread thread) { - auto profiler = std::unique_ptr<ThreadProfiler>(new ThreadProfiler(thread)); - g_child_thread_profiler_sequence_local_storage.Get().Set(std::move(profiler)); -} - -void ThreadProfiler::SetServiceManagerConnectorForChildProcess( - service_manager::Connector* connector) { - DCHECK_NE(metrics::CallStackProfileParams::BROWSER_PROCESS, GetProcess()); - metrics::mojom::CallStackProfileCollectorPtr browser_interface; - connector->BindInterface(content::mojom::kBrowserServiceName, - &browser_interface); - g_child_call_stack_profile_collector.Get().SetParentProfileCollector( - std::move(browser_interface)); -} - -ThreadProfiler::ThreadProfiler(metrics::CallStackProfileParams::Thread thread) - : startup_profile_params_(GetProcess(), - thread, - metrics::CallStackProfileParams::PROCESS_STARTUP, - metrics::CallStackProfileParams::MAY_SHUFFLE) { - if (!StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) - return; - - startup_profiler_ = std::make_unique<base::StackSamplingProfiler>( - base::PlatformThread::CurrentId(), GetSamplingParams(), - BindRepeating(&ThreadProfiler::ReceiveStartupProfiles, - GetReceiverCallback(&startup_profile_params_))); - startup_profiler_->Start(); -} - -base::StackSamplingProfiler::CompletedCallback -ThreadProfiler::GetReceiverCallback( - metrics::CallStackProfileParams* profile_params) { - profile_params->start_timestamp = base::TimeTicks::Now(); - // TODO(wittman): Simplify the approach to getting the profiler callback - // across CallStackProfileMetricsProvider and - // ChildCallStackProfileCollector. Ultimately both should expose functions - // like - // - // void ReceiveCompletedProfiles( - // const metrics::CallStackProfileParams& profile_params, - // base::TimeTicks profile_start_time, - // base::StackSamplingProfiler::CallStackProfiles profiles); - // - // and this function should bind the passed profile_params and - // base::TimeTicks::Now() to those functions. - if (GetProcess() == metrics::CallStackProfileParams::BROWSER_PROCESS) { - return metrics::CallStackProfileMetricsProvider:: - GetProfilerCallbackForBrowserProcess(profile_params); - } - return g_child_call_stack_profile_collector.Get() - .ChildCallStackProfileCollector::GetProfilerCallback(*profile_params); -} - -// static -base::Optional<base::StackSamplingProfiler::SamplingParams> -ThreadProfiler::ReceiveStartupProfiles( - const base::StackSamplingProfiler::CompletedCallback& receiver_callback, - base::StackSamplingProfiler::CallStackProfiles profiles) { - receiver_callback.Run(std::move(profiles)); - return base::Optional<base::StackSamplingProfiler::SamplingParams>(); -}
diff --git a/chrome/common/thread_profiler.h b/chrome/common/thread_profiler.h deleted file mode 100644 index d5dbd95..0000000 --- a/chrome/common/thread_profiler.h +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2018 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_COMMON_THREAD_PROFILER_H_ -#define CHROME_COMMON_THREAD_PROFILER_H_ - -#include <memory> - -#include "base/macros.h" -#include "base/profiler/stack_sampling_profiler.h" -#include "base/single_thread_task_runner.h" -#include "components/metrics/call_stack_profile_params.h" - -namespace service_manager { -class Connector; -} - -// ThreadProfiler performs startup and periodic profiling of Chrome -// threads. -class ThreadProfiler { - public: - ~ThreadProfiler(); - - // Creates a profiler for a main thread and immediately starts it. This - // function should only be used when profiling the main thread of a - // process. The returned profiler must be destroyed prior to thread exit to - // stop the profiling. SetMainThreadTaskRunner() should be called after the - // message loop has been started on the thread. - static std::unique_ptr<ThreadProfiler> CreateAndStartOnMainThread( - metrics::CallStackProfileParams::Thread thread); - - // Creates a profiler for a child thread and immediately starts it. This - // should be called from a task posted on the child thread immediately after - // thread start. The thread will be profiled until exit. - static void StartOnChildThread( - metrics::CallStackProfileParams::Thread thread); - - // This function must be called within child processes to supply the Service - // Manager's connector, to bind the interface through which profiles are sent - // back to the browser process. - // - // Note that the metrics::CallStackProfileCollector interface also must be - // exposed to the child process, and metrics::mojom::CallStackProfileCollector - // declared in chrome_content_browser_manifest_overlay.json, for the binding - // to succeed. - static void SetServiceManagerConnectorForChildProcess( - service_manager::Connector* connector); - - private: - // Creates the profiler. - explicit ThreadProfiler(metrics::CallStackProfileParams::Thread thread); - - // Gets the completed callback for the ultimate receiver of the profiles. - base::StackSamplingProfiler::CompletedCallback GetReceiverCallback( - metrics::CallStackProfileParams* profile_params); - - // Receives |profiles| from the StackSamplingProfiler and forwards them on to - // the original |receiver_callback|. Note that we must obtain and bind the - // original receiver callback prior to the start of collection because the - // collection start time is currently recorded when obtaining the callback in - // some collection scenarios. The implementation contains a TODO to fix this. - static base::Optional<base::StackSamplingProfiler::SamplingParams> - ReceiveStartupProfiles( - const base::StackSamplingProfiler::CompletedCallback& receiver_callback, - base::StackSamplingProfiler::CallStackProfiles profiles); - - // TODO(wittman): Make const after cleaning up the existing continuous - // collection support. - metrics::CallStackProfileParams startup_profile_params_; - - std::unique_ptr<base::StackSamplingProfiler> startup_profiler_; - - DISALLOW_COPY_AND_ASSIGN(ThreadProfiler); -}; - -#endif // CHROME_COMMON_THREAD_PROFILER_H_
diff --git a/chrome/gpu/chrome_content_gpu_client.cc b/chrome/gpu/chrome_content_gpu_client.cc index 8ce2aa3..9b03c1c 100644 --- a/chrome/gpu/chrome_content_gpu_client.cc +++ b/chrome/gpu/chrome_content_gpu_client.cc
@@ -4,12 +4,20 @@ #include "chrome/gpu/chrome_content_gpu_client.h" -#include <string> #include <utility> +#include "base/command_line.h" +#include "base/lazy_instance.h" +#include "base/threading/platform_thread.h" +#include "base/threading/sequence_local_storage_slot.h" #include "base/time/time.h" +#include "chrome/common/stack_sampling_configuration.h" +#include "components/metrics/child_call_stack_profile_collector.h" #include "content/public/child/child_thread.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/service_names.mojom.h" #include "mojo/public/cpp/bindings/strong_binding.h" +#include "services/service_manager/public/cpp/connector.h" #if BUILDFLAG(ENABLE_LIBRARY_CDMS) #include "media/cdm/cdm_paths.h" @@ -27,9 +35,53 @@ #include "ui/ozone/public/surface_factory_ozone.h" #endif +namespace { + +base::LazyInstance<metrics::ChildCallStackProfileCollector>::Leaky + g_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER; + +// The profiler object is stored in a SequenceLocalStorageSlot on the IO thread +// so that it will be destroyed when the IO thread stops. +base::LazyInstance<base::SequenceLocalStorageSlot< + std::unique_ptr<base::StackSamplingProfiler>>>::Leaky + io_thread_sampling_profiler = LAZY_INSTANCE_INITIALIZER; + +// Starts to profile the IO thread. +void StartIOThreadProfiling() { + StackSamplingConfiguration* config = StackSamplingConfiguration::Get(); + + if (config->IsProfilerEnabledForCurrentProcess()) { + auto profiler = std::make_unique<base::StackSamplingProfiler>( + base::PlatformThread::CurrentId(), + config->GetSamplingParamsForCurrentProcess(), + g_call_stack_profile_collector.Get().GetProfilerCallback( + metrics::CallStackProfileParams( + metrics::CallStackProfileParams::GPU_PROCESS, + metrics::CallStackProfileParams::IO_THREAD, + metrics::CallStackProfileParams::PROCESS_STARTUP, + metrics::CallStackProfileParams::MAY_SHUFFLE))); + + profiler->Start(); + io_thread_sampling_profiler.Get().Set(std::move(profiler)); + } +} + +} // namespace + ChromeContentGpuClient::ChromeContentGpuClient() - : main_thread_profiler_(ThreadProfiler::CreateAndStartOnMainThread( - metrics::CallStackProfileParams::GPU_MAIN_THREAD)) { + : stack_sampling_profiler_( + base::PlatformThread::CurrentId(), + StackSamplingConfiguration::Get() + ->GetSamplingParamsForCurrentProcess(), + g_call_stack_profile_collector.Get().GetProfilerCallback( + metrics::CallStackProfileParams( + metrics::CallStackProfileParams::GPU_PROCESS, + metrics::CallStackProfileParams::GPU_MAIN_THREAD, + metrics::CallStackProfileParams::PROCESS_STARTUP, + metrics::CallStackProfileParams::MAY_SHUFFLE))) { + if (StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) + stack_sampling_profiler_.Start(); + #if defined(OS_CHROMEOS) protected_buffer_manager_ = std::make_unique<arc::ProtectedBufferManager>(); #endif @@ -66,15 +118,16 @@ base::Unretained(protected_buffer_manager_.get()))); #endif - ThreadProfiler::SetServiceManagerConnectorForChildProcess( - content::ChildThread::Get()->GetConnector()); + metrics::mojom::CallStackProfileCollectorPtr browser_interface; + content::ChildThread::Get()->GetConnector()->BindInterface( + content::mojom::kBrowserServiceName, &browser_interface); + g_call_stack_profile_collector.Get().SetParentProfileCollector( + std::move(browser_interface)); } void ChromeContentGpuClient::PostIOThreadCreated( base::SingleThreadTaskRunner* io_task_runner) { - io_task_runner->PostTask( - FROM_HERE, base::BindOnce(&ThreadProfiler::StartOnChildThread, - metrics::CallStackProfileParams::IO_THREAD)); + io_task_runner->PostTask(FROM_HERE, base::BindOnce(&StartIOThreadProfiling)); } #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
diff --git a/chrome/gpu/chrome_content_gpu_client.h b/chrome/gpu/chrome_content_gpu_client.h index bd08470..deb0202c 100644 --- a/chrome/gpu/chrome_content_gpu_client.h +++ b/chrome/gpu/chrome_content_gpu_client.h
@@ -6,11 +6,10 @@ #define CHROME_GPU_CHROME_CONTENT_GPU_CLIENT_H_ #include <memory> -#include <string> #include "base/macros.h" +#include "base/profiler/stack_sampling_profiler.h" #include "base/single_thread_task_runner.h" -#include "chrome/common/thread_profiler.h" #include "content/public/gpu/content_gpu_client.h" #if defined(OS_CHROMEOS) @@ -53,8 +52,8 @@ ::arc::mojom::ProtectedBufferManagerRequest request); #endif - // Used to profile main thread startup. - std::unique_ptr<ThreadProfiler> main_thread_profiler_; + // Used to profile process startup. + base::StackSamplingProfiler stack_sampling_profiler_; #if defined(OS_CHROMEOS) gpu::GpuPreferences gpu_preferences_;
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 5386c68..d98e164d 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -15,9 +15,11 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics_action.h" +#include "base/profiler/stack_sampling_profiler.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequence_local_storage_slot.h" #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" @@ -38,7 +40,7 @@ #include "chrome/common/profiling/memlog_allocator_shim.h" #include "chrome/common/render_messages.h" #include "chrome/common/secure_origin_whitelist.h" -#include "chrome/common/thread_profiler.h" +#include "chrome/common/stack_sampling_configuration.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" @@ -78,6 +80,7 @@ #include "components/dom_distiller/core/url_constants.h" #include "components/error_page/common/error.h" #include "components/error_page/common/localized_error.h" +#include "components/metrics/child_call_stack_profile_collector.h" #include "components/network_hints/renderer/prescient_networking_dispatcher.h" #include "components/pdf/renderer/pepper_pdf_host.h" #include "components/safe_browsing/renderer/threat_dom_details.h" @@ -226,6 +229,35 @@ namespace { +base::LazyInstance<metrics::ChildCallStackProfileCollector>::Leaky + g_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER; + +// The profiler object is stored in a SequenceLocalStorageSlot on the compositor +// thread so that it will be destroyed when the compositor thread stops. +base::LazyInstance<base::SequenceLocalStorageSlot< + std::unique_ptr<base::StackSamplingProfiler>>>::Leaky + g_compositor_thread_sampling_profiler = LAZY_INSTANCE_INITIALIZER; + +// Starts to profile the compositor thread. +void StartCompositorThreadProfiling() { + StackSamplingConfiguration* config = StackSamplingConfiguration::Get(); + if (!config->IsProfilerEnabledForCurrentProcess()) + return; + + auto profiler_callback = + g_call_stack_profile_collector.Get().GetProfilerCallback( + metrics::CallStackProfileParams( + metrics::CallStackProfileParams::RENDERER_PROCESS, + metrics::CallStackProfileParams::COMPOSITOR_THREAD, + metrics::CallStackProfileParams::PROCESS_STARTUP, + metrics::CallStackProfileParams::MAY_SHUFFLE)); + auto profiler = std::make_unique<base::StackSamplingProfiler>( + base::PlatformThread::CurrentId(), + config->GetSamplingParamsForCurrentProcess(), profiler_callback); + profiler->Start(); + g_compositor_thread_sampling_profiler.Get().Set(std::move(profiler)); +} + void RecordYouTubeRewriteUMA(internal::YouTubeRewriteStatus status) { UMA_HISTOGRAM_ENUMERATION(internal::kFlashYouTubeRewriteUMA, status, internal::NUM_PLUGIN_ERROR); @@ -1218,14 +1250,14 @@ // Do not start the profiler for extension processes. if (IsStandaloneExtensionProcess()) return; - - ThreadProfiler::SetServiceManagerConnectorForChildProcess( - content::ChildThread::Get()->GetConnector()); + metrics::mojom::CallStackProfileCollectorPtr browser_interface; + content::ChildThread::Get()->GetConnector()->BindInterface( + content::mojom::kBrowserServiceName, &browser_interface); + g_call_stack_profile_collector.Get().SetParentProfileCollector( + std::move(browser_interface)); compositor_thread_task_runner->PostTask( - FROM_HERE, - base::BindOnce(&ThreadProfiler::StartOnChildThread, - metrics::CallStackProfileParams::COMPOSITOR_THREAD)); + FROM_HERE, base::BindOnce(&StartCompositorThreadProfiling)); } bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index fa143f5..fdeafc2 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4685,7 +4685,6 @@ "../browser/ui/views/location_bar/star_view_browsertest.cc", "../browser/ui/views/omnibox/omnibox_view_views_browsertest.cc", "../browser/ui/views/passwords/manage_passwords_icon_view_interactive_uitest.cc", - "../browser/ui/views/sad_tab_view_interactive_uitest.cc", "../browser/ui/views/ssl_client_certificate_selector_browsertest.cc", "../browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc", "../browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h",
diff --git a/chrome/test/data/pdf/navigator_test.js b/chrome/test/data/pdf/navigator_test.js index 1e86f23b..55da969 100644 --- a/chrome/test/data/pdf/navigator_test.js +++ b/chrome/test/data/pdf/navigator_test.js
@@ -112,10 +112,10 @@ function() {}, function() {}, function() {}, 0, 1, 0); - var paramsParser = new OpenPDFParamsParser(function(name) { - if (name == 'US') + var paramsParser = new OpenPDFParamsParser(function(message) { + if (message.namedDestination == 'US') paramsParser.onNamedDestinationReceived(0); - else if (name == 'UY') + else if (message.namedDestination == 'UY') paramsParser.onNamedDestinationReceived(2); else paramsParser.onNamedDestinationReceived(-1);
diff --git a/chrome/test/data/pdf/params_parser_test.js b/chrome/test/data/pdf/params_parser_test.js index b3675f2..5bb91a5 100644 --- a/chrome/test/data/pdf/params_parser_test.js +++ b/chrome/test/data/pdf/params_parser_test.js
@@ -7,12 +7,13 @@ * Test named destinations. */ function testParamsParser() { - var paramsParser = new OpenPDFParamsParser(function(name) { - if (name == 'RU') + var paramsParser = new OpenPDFParamsParser(function(message) { + chrome.test.assertEq('getNamedDestination', message.type); + if (message.namedDestination == 'RU') paramsParser.onNamedDestinationReceived(26); - else if (name == 'US') + else if (message.namedDestination == 'US') paramsParser.onNamedDestinationReceived(0); - else if (name == 'UY') + else if (message.namedDestination == 'UY') paramsParser.onNamedDestinationReceived(22); else paramsParser.onNamedDestinationReceived(-1);
diff --git a/chrome/test/data/webui/chromeos/cr_onc_strings.js b/chrome/test/data/webui/chromeos/cr_onc_strings.js index e5401f9c..1134c3d 100644 --- a/chrome/test/data/webui/chromeos/cr_onc_strings.js +++ b/chrome/test/data/webui/chromeos/cr_onc_strings.js
@@ -7,9 +7,9 @@ * network_config.html and other network configuration UI. */ -var CrOncStrings = {}; +var CrOncTest = CrOncTest || {}; -CrOncStrings.overrideValues = function() { +CrOncTest.overrideCrOncStrings = function() { // From network_element_localized_string_provider.cc:AddOncLocalizedStrings. var oncKeys = { 'OncConnected': 'OncConnected',
diff --git a/chrome/test/data/webui/cr_components/cr_components_browsertest.js b/chrome/test/data/webui/cr_components/cr_components_browsertest.js index b9674b9..0ba829a1 100644 --- a/chrome/test/data/webui/cr_components/cr_components_browsertest.js +++ b/chrome/test/data/webui/cr_components/cr_components_browsertest.js
@@ -26,7 +26,7 @@ /** @override */ get browsePreload() { - throw 'this is abstract and should be overriden by subclasses'; + throw 'subclasses should override to load a WebUI page that includes it.'; }, /** @override */ @@ -52,13 +52,11 @@ __proto__: CrComponentsBrowserTest.prototype, /** @override */ - browsePreload: - 'chrome://resources/cr_components/chromeos/network/network_config.html', + browsePreload: 'chrome://internet-config-dialog', /** @override */ extraLibraries: CrComponentsBrowserTest.prototype.extraLibraries.concat([ ROOT_PATH + 'ui/webui/resources/js/assert.js', - ROOT_PATH + 'ui/webui/resources/js/load_time_data.js', ROOT_PATH + 'ui/webui/resources/js/promise_resolver.js', '../fake_chrome_event.js', '../chromeos/networking_private_constants.js',
diff --git a/chrome/test/data/webui/cr_components/network_config_test.js b/chrome/test/data/webui/cr_components/network_config_test.js index b16da2b0..0025bd5b7 100644 --- a/chrome/test/data/webui/cr_components/network_config_test.js +++ b/chrome/test/data/webui/cr_components/network_config_test.js
@@ -10,17 +10,7 @@ suiteSetup(function() { api_ = new chrome.FakeNetworkingPrivate(); - loadTimeData.data = { - networkCADoNotCheck: '', - networkCAUseDefault: '', - networkCertificateName: '', - networkCertificateNameHardwareBacked: '', - networkCertificateNoneInstalled: '', - networkConfigSaveCredentials: '', - networkConfigShare: '', - showPassword: '', - }; - CrOncStrings.overrideValues(); + CrOncTest.overrideCrOncStrings(); }); function setNetworkConfig(networkProperties) {
diff --git a/components/background_task_scheduler/BUILD.gn b/components/background_task_scheduler/BUILD.gn index fde12b7..9525aff 100644 --- a/components/background_task_scheduler/BUILD.gn +++ b/components/background_task_scheduler/BUILD.gn
@@ -95,6 +95,5 @@ "//base:base_junit_test_support", "//third_party/junit", ] - srcjar_deps = [ "//base:base_build_config_gen" ] } }
diff --git a/components/crash/content/app/breakpad_linux.cc b/components/crash/content/app/breakpad_linux.cc index c72cd36..460f7ac 100644 --- a/components/crash/content/app/breakpad_linux.cc +++ b/components/crash/content/app/breakpad_linux.cc
@@ -556,16 +556,20 @@ #if defined(OS_ANDROID) // Writes the "package" field, which is in the format: -// $PACKAGE_NAME v$VERSION_CODE ($VERSION_NAME) +// $FIREBASE_APP_ID v$VERSION_CODE ($VERSION_NAME) void WriteAndroidPackage(MimeWriter& writer, base::android::BuildInfo* android_build_info) { + // Don't write the field if no Firebase ID is set. + if (android_build_info->firebase_app_id()[0] == '\0') { + return; + } // The actual size limits on packageId and versionName are quite generous. // Limit to a reasonable size rather than allocating theoretical limits. const int kMaxSize = 1024; char buf[kMaxSize]; // Not using sprintf to ensure no heap allocations. - my_strlcpy(buf, android_build_info->package_name(), kMaxSize); + my_strlcpy(buf, android_build_info->firebase_app_id(), kMaxSize); my_strlcat(buf, " v", kMaxSize); my_strlcat(buf, android_build_info->package_version_code(), kMaxSize); my_strlcat(buf, " (", kMaxSize);
diff --git a/components/cronet/native/cronet.idl b/components/cronet/native/cronet.idl index 908770b..2be96e4f 100644 --- a/components/cronet/native/cronet.idl +++ b/components/cronet/native/cronet.idl
@@ -52,8 +52,8 @@ OnDestroy(Buffer buffer); }; -// Base exception passed to UrlRequestCallback.onFailed(). -struct Exception { +// Base error passed to UrlRequestCallback.onFailed(). +struct Error { enum ERROR_CODE { /** * Error code indicating the error returned by app callback. @@ -124,7 +124,13 @@ /** * Error code, one of ERROR_* values. */ - ERROR_CODE error_code = ERROR_CALLBACK; + ERROR_CODE errorCode = ERROR_CALLBACK; + + /** + * Message, explaining the error. + */ + string message; + /** * Cronet internal error code. This may provide more specific error * diagnosis than |error_code|, but the constant values may change over time. @@ -201,6 +207,14 @@ * Host name is invalid */ ILLEGAL_ARGUMENT_INVALID_HOSTNAME = -103, + /** + * Invalid http method + */ + ILLEGAL_ARGUMENT_INVALID_HTTP_METHOD = -104, + /** + * Invalid http header + */ + ILLEGAL_ARGUMENT_INVALID_HTTP_HEADER = -105, /** * Illegal state @@ -218,6 +232,22 @@ * The engine has already started */ ILLEGAL_STATE_ENGINE_ALREADY_STARTED = -203, + /** + * The request has already started + */ + ILLEGAL_STATE_REQUEST_ALREADY_STARTED = -204, + /** + * The request is not initialized + */ + ILLEGAL_STATE_REQUEST_NOT_INITIALIZED = -205, + /** + * No redirect to follow + */ + ILLEGAL_STATE_UNEXPECTED_REDIRECT = -206, + /** + * Unexpected read attempt + */ + ILLEGAL_STATE_UNEXPECTED_READ = -207, /** * Null pointer or empty data @@ -235,6 +265,34 @@ * The pin expiration date cannot be null */ NULL_POINTER_EXPIRATION_DATE = -303, + /** + * Engine is required + */ + NULL_POINTER_ENGINE = -304, + /** + * URL is required + */ + NULL_POINTER_URL = -305, + /** + * Callback is required + */ + NULL_POINTER_CALLBACK = -306, + /** + * Executor is required + */ + NULL_POINTER_EXECUTOR = -307, + /** + * Method is required + */ + NULL_POINTER_METHOD = -308, + /** + * Invalid header name + */ + NULL_POINTER_HEADER_NAME = -309, + /** + * Invalid header value + */ + NULL_POINTER_HEADER_VALUE = -310, }; /** @@ -256,17 +314,17 @@ * The file can be viewed using a Chrome browser navigated to * chrome://net-internals/#import * Returns |true| if netlog has started successfully, |false| otherwise. - * @param fileName the complete file path. It must not be empty. If the file + * @param file_name the complete file path. It must not be empty. If the file * exists, it is truncated before starting. If actively logging, * this method is ignored. - * @param logAll {@code true} to include basic events, user cookies, + * @param log_all {@code true} to include basic events, user cookies, * credentials and all transferred bytes in the log. This option presents * a privacy risk, since it exposes the user's credentials, and should * only be used with the user's consent and in situations where the log * won't be public. {@code false} to just include basic events. */ [Sync] - StartNetLogToFile(string fileName, bool logAll) => (bool started); + StartNetLogToFile(string file_name, bool log_all) => (bool started); /** * Stops NetLog logging and flushes file to disk. If a logging session is @@ -292,14 +350,14 @@ * Returns a human-readable version string of the engine. */ [Sync] - GetVersionString() => (string versionString); + GetVersionString() => (string version_string); /** * Returns default human-readable version string of the engine. Can be used * before StartWithParams() is called. */ [Sync] - GetDefaultUserAgent() => (string defaultUserAgent); + GetDefaultUserAgent() => (string default_user_agent); }; /** @@ -319,7 +377,7 @@ /** * Alternate port to use for QUIC. */ - int32 alternatePort = 0; + int32 alternate_port = 0; }; /** @@ -350,17 +408,17 @@ * that can be used if the control of the primary private key has been * lost, it is highly recommended to supply one. */ - array<string> pinsSha256; + array<string> pins_sha256; /** * Indicates whether the pinning policy should be applied to subdomains of |host|. */ - bool includeSubdomains = false; + bool include_subdomains = false; /** * The expiration date for the pins in milliseconds since epoch (as in java.util.Date). */ - int64 expirationDate; + int64 expiration_date; }; /** @@ -373,44 +431,44 @@ * Override strict result checking for all operations that return RESULT. * If set to true, then failed result will cause native crash via SIGABORT. */ - bool enableCheckResult = true; + bool enable_check_result = true; /** * Override of the User-Agent header for all requests. An explicitly * set User-Agent header will override a value set using this param. */ - string userAgent; + string user_agent; /** * Sets a default value for the Accept-Language header value for UrlRequests * created by this engine. Explicitly setting the Accept-Language header * value for individual UrlRequests will override this value. */ - string acceptLanguage; + string accept_language; /** * Directory for HTTP Cache and Prefs Storage. The directory must exist. */ - string storagePath; + string storage_path; /** * Whether <a href="https://www.chromium.org/quic">QUIC</a> protocol * is enabled. If QUIC is enabled, then QUIC User Agent Id * containing application name and Cronet version is sent to the server. */ - bool enableQuic = false; + bool enable_quic = false; /** * Whether <a href="https://tools.ietf.org/html/rfc7540">HTTP/2</a> * protocol is enabled. */ - bool enableHttp2 = true; + bool enable_http2 = true; /** * Whether <a href="https://tools.ietf.org/html/rfc7932">Brotli</a> compression is * enabled. If enabled, Brotli will be advertised in Accept-Encoding request headers. */ - bool enableBrotli = true; + bool enable_brotli = true; /** * Enables or disables caching of HTTP data and other information like QUIC @@ -439,23 +497,23 @@ */ DISK = 3 }; - HTTP_CACHE_MODE httpCacheMode = DISABLED; + HTTP_CACHE_MODE http_cache_mode = DISABLED; /** * Maximum size in bytes used to cache data (advisory and maybe exceeded at * times). */ - int64 httpCacheMaxSize = 0; + int64 http_cache_max_size = 0; /** * Hints that hosts support QUIC. */ - array<QuicHint> quicHints; + array<QuicHint> quic_hints; /** * Pins a set of public keys for given hosts. See |PublicKeyPins| for explanation. */ - array<PublicKeyPins> publicKeyPins; + array<PublicKeyPins> public_key_pins; /** * Enables or disables public key pinning bypass for local trust anchors. Disabling the @@ -467,12 +525,12 @@ * information see 'How does key pinning interact with local proxies and filters?' at * https://www.chromium.org/Home/chromium-security/security-faq */ - bool enablePublicKeyPinningBypassForLocalTrustAnchors = true; + bool enable_public_key_pinning_bypass_for_local_trust_anchors = true; /** * JSON formatted experimental options to be used in Cronet Engine. */ - string experimentalOptions; + string experimental_options; }; /** @@ -501,44 +559,44 @@ * The URL chain. The first entry is the originally requested URL; * the following entries are redirects followed. */ - array<string> urlChain; + array<string> url_chain; /** * The HTTP status code. When a resource is retrieved from the cache, * whether it was revalidated or not, the original status code is returned. */ - int32 httpStatusCode; + int32 http_status_code; /** * The HTTP status text of the status line. For example, if the * request received a "HTTP/1.1 200 OK" response, this method returns "OK". */ - string httpStatusText; + string http_status_text; /** * Returns an unmodifiable list of response header field and value pairs. * The headers are in the same order they are received over the wire. */ - array<HttpHeader> allHeadersList; + array<HttpHeader> all_headers_list; /** * True if the response came from the cache, including * requests that were revalidated over the network before being retrieved * from the cache, failed otherwise. */ - bool wasCached; + bool was_cached; /** * The protocol (for example 'quic/1+spdy/3') negotiated with the server. * An empty string if no protocol was negotiated, the protocol is * not known, or when using plain HTTP or HTTPS. */ - string negotiatedProtocol; + string negotiated_protocol; /** * The proxy server that was used for the request. */ - string proxyServer; + string proxy_server; /** * A minimum count of bytes received from the network to process this @@ -547,7 +605,7 @@ * taken prior to decompression (for example GZIP and Brotli) and includes * headers and data from all redirects. */ - int64 receivedByteCount; + int64 received_byte_count; }; /** @@ -702,9 +760,9 @@ * * @param request Request being redirected. * @param info Response information. - * @param newLocationUrl Location where request is redirected. + * @param new_location_url Location where request is redirected. */ - OnRedirectReceived(UrlRequest request, UrlResponseInfo info, string newLocationUrl); + OnRedirectReceived(UrlRequest request, UrlResponseInfo info, string new_location_url); /** * Invoked when the final set of headers, after all redirects, is received. @@ -736,10 +794,10 @@ * @param request Request that received data. * @param info Response information. * @param buffer The buffer that was passed in to UrlRequest.read(), now - * containing the received data. The buffer's position is updated to the end of - * the received data. The buffer's limit is not changed. + * containing the received data. + * @param bytes_read The number of bytes read into buffer. */ - OnReadCompleted(UrlRequest request, UrlResponseInfo info, Buffer buffer); + OnReadCompleted(UrlRequest request, UrlResponseInfo info, Buffer buffer, uint64 bytes_read); /** * Invoked when request is completed successfully. Once invoked, no other @@ -760,7 +818,7 @@ * received. * @param error information about error. */ - OnFailed(UrlRequest request, UrlResponseInfo info, Exception error); + OnFailed(UrlRequest request, UrlResponseInfo info, Error error); /** * Invoked if request was canceled via UrlRequest.cancel(). Once @@ -781,16 +839,16 @@ /** * Called by UploadDataProvider when a read succeeds. * - * @param finalChunk For chunked uploads, |true| if this is the final + * @param final_chunk For chunked uploads, |true| if this is the final * read. It must be |false| for non-chunked uploads. */ - OnReadSucceeded(bool finalChunk); + OnReadSucceeded(bool final_chunk); /** * Called by UploadDataProvider when a read fails. * @param error to pass on to UrlRequestCallback.onFailed(). */ - OnReadError(Exception error); + OnReadError(Error error); /** * Called by UploadDataProvider when a rewind succeeds. @@ -802,7 +860,7 @@ * uploads is not supported. * @param error to pass on to UrlRequestCallback.onFailed(). */ - OnRewindError(Exception error); + OnRewindError(Error error); }; /** @@ -834,12 +892,12 @@ * the associated UrlRequest is canceled, one or the other must * still be called before resources can be safely freed. * - * @param uploadDataSink The object to notify when the read has completed, + * @param upload_data_sink The object to notify when the read has completed, * successfully or otherwise. * @param buffer The buffer to copy the read bytes into. Do not change * byteBuffer's limit. */ - Read(UploadDataSink uploadDataSink, Buffer buffer); + Read(UploadDataSink upload_data_sink, Buffer buffer); /** * Rewinds upload data. Each call must be followed be a single @@ -857,10 +915,10 @@ * follow redirects that preserve the upload body, and for retrying when the * server times out stale sockets. * - * @param uploadDataSink The object to notify when the rewind operation has + * @param upload_data_sink The object to notify when the rewind operation has * completed, successfully or otherwise. */ - Rewind(UploadDataSink uploadDataSink); + Rewind(UploadDataSink upload_data_sink); /** * Called when this UploadDataProvider is no longer needed by a request, so that resources @@ -887,23 +945,26 @@ * @param callback Callback that gets invoked on different events. * @param executor Executor on which all callbacks will be invoked. */ + [Sync] InitWithParams(Engine engine, string url, UrlRequestParams params, UrlRequestCallback callback, - Executor executor); + Executor executor) => (RESULT result); /** * Starts the request, all callbacks go to UrlRequestCallback. May only be called * once. May not be called if Cancel() has been called. */ - Start(); + [Sync] + Start() => (RESULT result); /** * Follows a pending redirect. Must only be called at most once for each * invocation of UrlRequestCallback.OnRedirectReceived(). */ - FollowRedirect(); + [Sync] + FollowRedirect() => (RESULT result); /** * Attempts to read part of the response body into the provided buffer. @@ -922,7 +983,8 @@ * modify buffer's position, limit, or data between its position and * limit until the request calls back into the UrlRequestCallback. */ - Read(Buffer buffer); + [Sync] + Read(Buffer buffer) => (RESULT result); /** * Cancels the request. Can be called at any time. @@ -991,18 +1053,18 @@ * * Allowed methods are "GET", "HEAD", "DELETE", "POST" or "PUT". */ - string httpMethod; + string http_method; /** * Array of HTTP headers for this request.. */ - array<HttpHeader> requestHeaders; + array<HttpHeader> request_headers; /** * Disables cache for the request. If context is not set up to use cache, * this call has no effect. */ - bool disableCache = false; + bool disable_cache = false; /** * Priority of the request which should be one of the REQUEST_PRIORITY values. @@ -1013,12 +1075,12 @@ * Upload data provider. Setting this value switches method to "POST" if not * explicitly set. Starting the request will fail if a Content-Type header is not set. */ - UploadDataProvider uploadDataProvider; + UploadDataProvider upload_data_provider; /** * Upload data provider executor that will be used to invoke uploadDataProvider. */ - Executor uploadDataProviderExecutor; + Executor upload_data_provider_executor; /** * Marks that the executors this request will use to notify callbacks (for @@ -1029,7 +1091,7 @@ * It should not be used if your callbacks perform disk I/O, acquire locks, or call into * other code you don't carefully control and audit. */ - bool allowDirectExecutor = false; + bool allow_direct_executor = false; /** * Associates the annotation object with this request. May add more than one. @@ -1037,3 +1099,27 @@ */ array<handle> annotations; }; + +/** + * Information about a finished request. + * TODO(mef): Define this to include metrics. + */ +struct RequestFinishedInfo { + /** + * The reason why the request finished. + */ + enum FINISHED_REASON { + /** + * The request succeeded. + */ + SUCCEEDED = 0, + /** + * The request failed or returned an error. + */ + FAILED = 1, + /** + * The request was canceled. + */ + CANCELED = 2, + }; +};
diff --git a/components/cronet/native/engine.cc b/components/cronet/native/engine.cc index 54de7a12..41ff26c4 100644 --- a/components/cronet/native/engine.cc +++ b/components/cronet/native/engine.cc
@@ -104,16 +104,16 @@ cronet::EnsureInitialized(); base::AutoLock lock(lock_); - enable_check_result_ = params->enableCheckResult; + enable_check_result_ = params->enable_check_result; if (context_) { return CheckResult(Cronet_RESULT_ILLEGAL_STATE_ENGINE_ALREADY_STARTED); } URLRequestContextConfigBuilder context_config_builder; - context_config_builder.enable_quic = params->enableQuic; - context_config_builder.enable_spdy = params->enableHttp2; - context_config_builder.enable_brotli = params->enableBrotli; - switch (params->httpCacheMode) { + context_config_builder.enable_quic = params->enable_quic; + context_config_builder.enable_spdy = params->enable_http2; + context_config_builder.enable_brotli = params->enable_brotli; + switch (params->http_cache_mode) { case Cronet_EngineParams_HTTP_CACHE_MODE_DISABLED: context_config_builder.http_cache = URLRequestContextConfig::DISABLED; break; @@ -122,45 +122,45 @@ break; case Cronet_EngineParams_HTTP_CACHE_MODE_DISK: context_config_builder.http_cache = URLRequestContextConfig::DISK; - if (!base::DirectoryExists(base::FilePath(params->storagePath))) { + if (!base::DirectoryExists(base::FilePath(params->storage_path))) { return CheckResult( Cronet_RESULT_ILLEGAL_ARGUMENT_STORAGE_PATH_MUST_EXIST); } if (!SharedEngineState::GetInstance()->MarkStoragePathInUse( - params->storagePath)) { - LOG(ERROR) << "Disk cache path " << params->storagePath + params->storage_path)) { + LOG(ERROR) << "Disk cache path " << params->storage_path << " is already used, cache disabled."; return CheckResult(Cronet_RESULT_ILLEGAL_STATE_STORAGE_PATH_IN_USE); } - in_use_storage_path_ = params->storagePath; + in_use_storage_path_ = params->storage_path; break; default: context_config_builder.http_cache = URLRequestContextConfig::DISABLED; } - context_config_builder.http_cache_max_size = params->httpCacheMaxSize; - context_config_builder.storage_path = params->storagePath; - context_config_builder.accept_language = params->acceptLanguage; - context_config_builder.user_agent = params->userAgent; - context_config_builder.experimental_options = params->experimentalOptions; + context_config_builder.http_cache_max_size = params->http_cache_max_size; + context_config_builder.storage_path = params->storage_path; + context_config_builder.accept_language = params->accept_language; + context_config_builder.user_agent = params->user_agent; + context_config_builder.experimental_options = params->experimental_options; context_config_builder.bypass_public_key_pinning_for_local_trust_anchors = - params->enablePublicKeyPinningBypassForLocalTrustAnchors; + params->enable_public_key_pinning_bypass_for_local_trust_anchors; std::unique_ptr<URLRequestContextConfig> config = context_config_builder.Build(); - for (const auto& publicKeyPins : params->publicKeyPins) { + for (const auto& public_key_pins : params->public_key_pins) { auto pkp = std::make_unique<URLRequestContextConfig::Pkp>( - publicKeyPins->host, publicKeyPins->includeSubdomains, - base::Time::FromJavaTime(publicKeyPins->expirationDate)); + public_key_pins->host, public_key_pins->include_subdomains, + base::Time::FromJavaTime(public_key_pins->expiration_date)); if (pkp->host.empty()) return CheckResult(Cronet_RESULT_NULL_POINTER_HOSTNAME); if (!IsValidHostnameForPkp(pkp->host)) return CheckResult(Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_HOSTNAME); if (pkp->expiration_date.is_null()) return CheckResult(Cronet_RESULT_NULL_POINTER_EXPIRATION_DATE); - if (publicKeyPins->pinsSha256.empty()) + if (public_key_pins->pins_sha256.empty()) return CheckResult(Cronet_RESULT_NULL_POINTER_SHA256_PINS); - for (const auto& pin_sha256 : publicKeyPins->pinsSha256) { + for (const auto& pin_sha256 : public_key_pins->pins_sha256) { net::HashValue pin_hash; if (!pin_hash.FromString(pin_sha256)) return CheckResult(Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_PIN); @@ -169,10 +169,10 @@ config->pkp_list.push_back(std::move(pkp)); } - for (const auto& quic_hint : params->quicHints) { + for (const auto& quic_hint : params->quic_hints) { config->quic_hints.push_back( std::make_unique<URLRequestContextConfig::QuicHint>( - quic_hint->host, quic_hint->port, quic_hint->alternatePort)); + quic_hint->host, quic_hint->port, quic_hint->alternate_port)); } context_ = std::make_unique<CronetURLRequestContext>( @@ -192,11 +192,11 @@ return CheckResult(Cronet_RESULT_SUCCESS); } -bool Cronet_EngineImpl::StartNetLogToFile(CharString fileName, bool logAll) { +bool Cronet_EngineImpl::StartNetLogToFile(CharString file_name, bool log_all) { base::AutoLock lock(lock_); if (is_logging_ || !context_) return false; - is_logging_ = context_->StartNetLogToFile(fileName, logAll); + is_logging_ = context_->StartNetLogToFile(file_name, log_all); return is_logging_; }
diff --git a/components/cronet/native/engine.h b/components/cronet/native/engine.h index 67dcc60..706fdfb 100644 --- a/components/cronet/native/engine.h +++ b/components/cronet/native/engine.h
@@ -27,7 +27,7 @@ void SetContext(Cronet_EngineContext context) override; Cronet_EngineContext GetContext() override; Cronet_RESULT StartWithParams(Cronet_EngineParamsPtr params) override; - bool StartNetLogToFile(CharString fileName, bool logAll) override; + bool StartNetLogToFile(CharString file_name, bool log_all) override; void StopNetLog() override; CharString GetVersionString() override; CharString GetDefaultUserAgent() override;
diff --git a/components/cronet/native/engine_test.cc b/components/cronet/native/engine_test.cc index 752c6ee..d61bd81 100644 --- a/components/cronet/native/engine_test.cc +++ b/components/cronet/native/engine_test.cc
@@ -28,7 +28,7 @@ TEST_F(EngineTest, StartCronetEngine) { Cronet_EnginePtr engine = Cronet_Engine_Create(); Cronet_EngineParamsPtr engine_params = Cronet_EngineParams_Create(); - Cronet_EngineParams_set_userAgent(engine_params, kUserAgent); + Cronet_EngineParams_set_user_agent(engine_params, kUserAgent); EXPECT_EQ(Cronet_RESULT_SUCCESS, Cronet_Engine_StartWithParams(engine, engine_params)); Cronet_Engine_Destroy(engine); @@ -62,18 +62,19 @@ Cronet_EngineParamsPtr engine_params = Cronet_EngineParams_Create(); Cronet_EnginePtr engine = Cronet_Engine_Create(); // Disable runtime CHECK of the result, so it could be verified. - Cronet_EngineParams_set_enableCheckResult(engine_params, false); - Cronet_EngineParams_set_httpCacheMode( + Cronet_EngineParams_set_enable_check_result(engine_params, false); + Cronet_EngineParams_set_http_cache_mode( engine_params, Cronet_EngineParams_HTTP_CACHE_MODE_DISK); EXPECT_EQ(Cronet_RESULT_ILLEGAL_ARGUMENT_STORAGE_PATH_MUST_EXIST, Cronet_Engine_StartWithParams(engine, engine_params)); - Cronet_EngineParams_set_storagePath(engine_params, "InvalidPath"); + Cronet_EngineParams_set_storage_path(engine_params, "InvalidPath"); EXPECT_EQ(Cronet_RESULT_ILLEGAL_ARGUMENT_STORAGE_PATH_MUST_EXIST, Cronet_Engine_StartWithParams(engine, engine_params)); base::ScopedTempDir temp_dir; EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); base::FilePath temp_path = base::MakeAbsoluteFilePath(temp_dir.GetPath()); - Cronet_EngineParams_set_storagePath(engine_params, temp_path.value().c_str()); + Cronet_EngineParams_set_storage_path(engine_params, + temp_path.value().c_str()); // Now the engine should start successfully. EXPECT_EQ(Cronet_RESULT_SUCCESS, Cronet_Engine_StartWithParams(engine, engine_params)); @@ -98,10 +99,10 @@ Cronet_EngineParamsPtr engine_params = Cronet_EngineParams_Create(); Cronet_EnginePtr engine = Cronet_Engine_Create(); // Disable runtime CHECK of the result, so it could be verified. - Cronet_EngineParams_set_enableCheckResult(engine_params, false); + Cronet_EngineParams_set_enable_check_result(engine_params, false); // Try adding invalid public key pins. Cronet_PublicKeyPinsPtr public_key_pins = Cronet_PublicKeyPins_Create(); - Cronet_EngineParams_add_publicKeyPins(engine_params, public_key_pins); + Cronet_EngineParams_add_public_key_pins(engine_params, public_key_pins); EXPECT_EQ(Cronet_RESULT_NULL_POINTER_HOSTNAME, Cronet_Engine_StartWithParams(engine, engine_params)); Cronet_PublicKeyPins_set_host(public_key_pins, std::string(256, 'a').c_str()); @@ -115,7 +116,7 @@ EXPECT_EQ(Cronet_RESULT_NULL_POINTER_SHA256_PINS, Cronet_Engine_StartWithParams(engine, engine_params)); // Detect invalid pin. - Cronet_PublicKeyPins_add_pinsSha256(public_key_pins, "invalid_sha256"); + Cronet_PublicKeyPins_add_pins_sha256(public_key_pins, "invalid_sha256"); EXPECT_EQ(Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_PIN, Cronet_Engine_StartWithParams(engine, engine_params)); // THe engine cannot start with these params, and have to be destroyed. @@ -127,13 +128,13 @@ Cronet_EngineParamsPtr engine_params = Cronet_EngineParams_Create(); Cronet_EnginePtr engine = Cronet_Engine_Create(); // Disable runtime CHECK of the result, so it could be verified. - Cronet_EngineParams_set_enableCheckResult(engine_params, false); + Cronet_EngineParams_set_enable_check_result(engine_params, false); // Add valid public key pins. Cronet_PublicKeyPinsPtr public_key_pins = Cronet_PublicKeyPins_Create(); Cronet_PublicKeyPins_set_host(public_key_pins, "valid.host.name"); - Cronet_PublicKeyPins_add_pinsSha256( + Cronet_PublicKeyPins_add_pins_sha256( public_key_pins, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); - Cronet_EngineParams_add_publicKeyPins(engine_params, public_key_pins); + Cronet_EngineParams_add_public_key_pins(engine_params, public_key_pins); // The engine should start successfully. EXPECT_EQ(Cronet_RESULT_SUCCESS, Cronet_Engine_StartWithParams(engine, engine_params)); @@ -150,7 +151,7 @@ Cronet_EnginePtr engine = Cronet_Engine_Create(); Cronet_EngineParamsPtr engine_params = Cronet_EngineParams_Create(); - Cronet_EngineParams_set_experimentalOptions( + Cronet_EngineParams_set_experimental_options( engine_params, "{ \"QUIC\" : {\"max_server_configs_stored_in_properties\" : 8} }"); // Test that net log cannot start/stop before engine start.
diff --git a/components/cronet/native/generated/cronet.idl_c.h b/components/cronet/native/generated/cronet.idl_c.h index d8e1ff20..fbb365cc 100644 --- a/components/cronet/native/generated/cronet.idl_c.h +++ b/components/cronet/native/generated/cronet.idl_c.h
@@ -51,8 +51,8 @@ typedef void* Cronet_UrlRequestContext; // Forward declare structs. -typedef struct Cronet_Exception Cronet_Exception; -typedef struct Cronet_Exception* Cronet_ExceptionPtr; +typedef struct Cronet_Error Cronet_Error; +typedef struct Cronet_Error* Cronet_ErrorPtr; typedef struct Cronet_QuicHint Cronet_QuicHint; typedef struct Cronet_QuicHint* Cronet_QuicHintPtr; typedef struct Cronet_PublicKeyPins Cronet_PublicKeyPins; @@ -65,6 +65,8 @@ typedef struct Cronet_UrlResponseInfo* Cronet_UrlResponseInfoPtr; typedef struct Cronet_UrlRequestParams Cronet_UrlRequestParams; typedef struct Cronet_UrlRequestParams* Cronet_UrlRequestParamsPtr; +typedef struct Cronet_RequestFinishedInfo Cronet_RequestFinishedInfo; +typedef struct Cronet_RequestFinishedInfo* Cronet_RequestFinishedInfoPtr; // Declare enums typedef enum Cronet_RESULT { @@ -73,30 +75,43 @@ Cronet_RESULT_ILLEGAL_ARGUMENT_STORAGE_PATH_MUST_EXIST = -101, Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_PIN = -102, Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_HOSTNAME = -103, + Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_HTTP_METHOD = -104, + Cronet_RESULT_ILLEGAL_ARGUMENT_INVALID_HTTP_HEADER = -105, Cronet_RESULT_ILLEGAL_STATE = -200, Cronet_RESULT_ILLEGAL_STATE_STORAGE_PATH_IN_USE = -201, Cronet_RESULT_ILLEGAL_STATE_CANNOT_SHUTDOWN_ENGINE_FROM_NETWORK_THREAD = -202, Cronet_RESULT_ILLEGAL_STATE_ENGINE_ALREADY_STARTED = -203, + Cronet_RESULT_ILLEGAL_STATE_REQUEST_ALREADY_STARTED = -204, + Cronet_RESULT_ILLEGAL_STATE_REQUEST_NOT_INITIALIZED = -205, + Cronet_RESULT_ILLEGAL_STATE_UNEXPECTED_REDIRECT = -206, + Cronet_RESULT_ILLEGAL_STATE_UNEXPECTED_READ = -207, Cronet_RESULT_NULL_POINTER = -300, Cronet_RESULT_NULL_POINTER_HOSTNAME = -301, Cronet_RESULT_NULL_POINTER_SHA256_PINS = -302, Cronet_RESULT_NULL_POINTER_EXPIRATION_DATE = -303, + Cronet_RESULT_NULL_POINTER_ENGINE = -304, + Cronet_RESULT_NULL_POINTER_URL = -305, + Cronet_RESULT_NULL_POINTER_CALLBACK = -306, + Cronet_RESULT_NULL_POINTER_EXECUTOR = -307, + Cronet_RESULT_NULL_POINTER_METHOD = -308, + Cronet_RESULT_NULL_POINTER_HEADER_NAME = -309, + Cronet_RESULT_NULL_POINTER_HEADER_VALUE = -310, } Cronet_RESULT; -typedef enum Cronet_Exception_ERROR_CODE { - Cronet_Exception_ERROR_CODE_ERROR_CALLBACK = 0, - Cronet_Exception_ERROR_CODE_ERROR_HOSTNAME_NOT_RESOLVED = 1, - Cronet_Exception_ERROR_CODE_ERROR_INTERNET_DISCONNECTED = 2, - Cronet_Exception_ERROR_CODE_ERROR_NETWORK_CHANGED = 3, - Cronet_Exception_ERROR_CODE_ERROR_TIMED_OUT = 4, - Cronet_Exception_ERROR_CODE_ERROR_CONNECTION_CLOSED = 5, - Cronet_Exception_ERROR_CODE_ERROR_CONNECTION_TIMED_OUT = 6, - Cronet_Exception_ERROR_CODE_ERROR_CONNECTION_REFUSED = 7, - Cronet_Exception_ERROR_CODE_ERROR_CONNECTION_RESET = 8, - Cronet_Exception_ERROR_CODE_ERROR_ADDRESS_UNREACHABLE = 9, - Cronet_Exception_ERROR_CODE_ERROR_QUIC_PROTOCOL_FAILED = 10, - Cronet_Exception_ERROR_CODE_ERROR_OTHER = 11, -} Cronet_Exception_ERROR_CODE; +typedef enum Cronet_Error_ERROR_CODE { + Cronet_Error_ERROR_CODE_ERROR_CALLBACK = 0, + Cronet_Error_ERROR_CODE_ERROR_HOSTNAME_NOT_RESOLVED = 1, + Cronet_Error_ERROR_CODE_ERROR_INTERNET_DISCONNECTED = 2, + Cronet_Error_ERROR_CODE_ERROR_NETWORK_CHANGED = 3, + Cronet_Error_ERROR_CODE_ERROR_TIMED_OUT = 4, + Cronet_Error_ERROR_CODE_ERROR_CONNECTION_CLOSED = 5, + Cronet_Error_ERROR_CODE_ERROR_CONNECTION_TIMED_OUT = 6, + Cronet_Error_ERROR_CODE_ERROR_CONNECTION_REFUSED = 7, + Cronet_Error_ERROR_CODE_ERROR_CONNECTION_RESET = 8, + Cronet_Error_ERROR_CODE_ERROR_ADDRESS_UNREACHABLE = 9, + Cronet_Error_ERROR_CODE_ERROR_QUIC_PROTOCOL_FAILED = 10, + Cronet_Error_ERROR_CODE_ERROR_OTHER = 11, +} Cronet_Error_ERROR_CODE; typedef enum Cronet_EngineParams_HTTP_CACHE_MODE { Cronet_EngineParams_HTTP_CACHE_MODE_DISABLED = 0, @@ -113,6 +128,12 @@ Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_HIGHEST = 4, } Cronet_UrlRequestParams_REQUEST_PRIORITY; +typedef enum Cronet_RequestFinishedInfo_FINISHED_REASON { + Cronet_RequestFinishedInfo_FINISHED_REASON_SUCCEEDED = 0, + Cronet_RequestFinishedInfo_FINISHED_REASON_FAILED = 1, + Cronet_RequestFinishedInfo_FINISHED_REASON_CANCELED = 2, +} Cronet_RequestFinishedInfo_FINISHED_REASON; + typedef enum Cronet_UrlRequestStatusListener_Status { Cronet_UrlRequestStatusListener_Status_INVALID = -1, Cronet_UrlRequestStatusListener_Status_IDLE = 0, @@ -276,8 +297,8 @@ Cronet_EngineParamsPtr params); CRONET_EXPORT bool Cronet_Engine_StartNetLogToFile(Cronet_EnginePtr self, - CharString fileName, - bool logAll); + CharString file_name, + bool log_all); CRONET_EXPORT void Cronet_Engine_StopNetLog(Cronet_EnginePtr self); CRONET_EXPORT @@ -292,8 +313,8 @@ Cronet_EnginePtr self, Cronet_EngineParamsPtr params); typedef bool (*Cronet_Engine_StartNetLogToFileFunc)(Cronet_EnginePtr self, - CharString fileName, - bool logAll); + CharString file_name, + bool log_all); typedef void (*Cronet_Engine_StopNetLogFunc)(Cronet_EnginePtr self); typedef Cronet_RESULT (*Cronet_Engine_ShutdownFunc)(Cronet_EnginePtr self); typedef CharString (*Cronet_Engine_GetVersionStringFunc)(Cronet_EnginePtr self); @@ -364,7 +385,7 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - CharString newLocationUrl); + CharString new_location_url); CRONET_EXPORT void Cronet_UrlRequestCallback_OnResponseStarted( Cronet_UrlRequestCallbackPtr self, @@ -375,7 +396,8 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_BufferPtr buffer); + Cronet_BufferPtr buffer, + uint64_t bytes_read); CRONET_EXPORT void Cronet_UrlRequestCallback_OnSucceeded(Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, @@ -384,7 +406,7 @@ void Cronet_UrlRequestCallback_OnFailed(Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_ExceptionPtr error); + Cronet_ErrorPtr error); CRONET_EXPORT void Cronet_UrlRequestCallback_OnCanceled(Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, @@ -395,7 +417,7 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - CharString newLocationUrl); + CharString new_location_url); typedef void (*Cronet_UrlRequestCallback_OnResponseStartedFunc)( Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, @@ -404,7 +426,8 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_BufferPtr buffer); + Cronet_BufferPtr buffer, + uint64_t bytes_read); typedef void (*Cronet_UrlRequestCallback_OnSucceededFunc)( Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, @@ -413,7 +436,7 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_ExceptionPtr error); + Cronet_ErrorPtr error); typedef void (*Cronet_UrlRequestCallback_OnCanceledFunc)( Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, @@ -445,28 +468,28 @@ // The app calls them to manipulate Cronet_UploadDataSink. CRONET_EXPORT void Cronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self, - bool finalChunk); + bool final_chunk); CRONET_EXPORT void Cronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self, - Cronet_ExceptionPtr error); + Cronet_ErrorPtr error); CRONET_EXPORT void Cronet_UploadDataSink_OnRewindSucceded(Cronet_UploadDataSinkPtr self); CRONET_EXPORT void Cronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self, - Cronet_ExceptionPtr error); + Cronet_ErrorPtr error); // Concrete interface Cronet_UploadDataSink is implemented by Cronet. // The app can implement these for testing / mocking. typedef void (*Cronet_UploadDataSink_OnReadSucceededFunc)( Cronet_UploadDataSinkPtr self, - bool finalChunk); + bool final_chunk); typedef void (*Cronet_UploadDataSink_OnReadErrorFunc)( Cronet_UploadDataSinkPtr self, - Cronet_ExceptionPtr error); + Cronet_ErrorPtr error); typedef void (*Cronet_UploadDataSink_OnRewindSuccededFunc)( Cronet_UploadDataSinkPtr self); typedef void (*Cronet_UploadDataSink_OnRewindErrorFunc)( Cronet_UploadDataSinkPtr self, - Cronet_ExceptionPtr error); + Cronet_ErrorPtr error); // Concrete interface Cronet_UploadDataSink is implemented by Cronet. // The app can use this for testing / mocking. CRONET_EXPORT Cronet_UploadDataSinkPtr Cronet_UploadDataSink_CreateStub( @@ -496,11 +519,12 @@ int64_t Cronet_UploadDataProvider_GetLength(Cronet_UploadDataProviderPtr self); CRONET_EXPORT void Cronet_UploadDataProvider_Read(Cronet_UploadDataProviderPtr self, - Cronet_UploadDataSinkPtr uploadDataSink, + Cronet_UploadDataSinkPtr upload_data_sink, Cronet_BufferPtr buffer); CRONET_EXPORT -void Cronet_UploadDataProvider_Rewind(Cronet_UploadDataProviderPtr self, - Cronet_UploadDataSinkPtr uploadDataSink); +void Cronet_UploadDataProvider_Rewind( + Cronet_UploadDataProviderPtr self, + Cronet_UploadDataSinkPtr upload_data_sink); CRONET_EXPORT void Cronet_UploadDataProvider_Close(Cronet_UploadDataProviderPtr self); // The app implements abstract interface Cronet_UploadDataProvider by defining @@ -509,11 +533,11 @@ Cronet_UploadDataProviderPtr self); typedef void (*Cronet_UploadDataProvider_ReadFunc)( Cronet_UploadDataProviderPtr self, - Cronet_UploadDataSinkPtr uploadDataSink, + Cronet_UploadDataSinkPtr upload_data_sink, Cronet_BufferPtr buffer); typedef void (*Cronet_UploadDataProvider_RewindFunc)( Cronet_UploadDataProviderPtr self, - Cronet_UploadDataSinkPtr uploadDataSink); + Cronet_UploadDataSinkPtr upload_data_sink); typedef void (*Cronet_UploadDataProvider_CloseFunc)( Cronet_UploadDataProviderPtr self); // The app creates an instance of Cronet_UploadDataProvider by providing custom @@ -539,18 +563,20 @@ // Concrete methods of Cronet_UrlRequest implemented by Cronet. // The app calls them to manipulate Cronet_UrlRequest. CRONET_EXPORT -void Cronet_UrlRequest_InitWithParams(Cronet_UrlRequestPtr self, - Cronet_EnginePtr engine, - CharString url, - Cronet_UrlRequestParamsPtr params, - Cronet_UrlRequestCallbackPtr callback, - Cronet_ExecutorPtr executor); +Cronet_RESULT Cronet_UrlRequest_InitWithParams( + Cronet_UrlRequestPtr self, + Cronet_EnginePtr engine, + CharString url, + Cronet_UrlRequestParamsPtr params, + Cronet_UrlRequestCallbackPtr callback, + Cronet_ExecutorPtr executor); CRONET_EXPORT -void Cronet_UrlRequest_Start(Cronet_UrlRequestPtr self); +Cronet_RESULT Cronet_UrlRequest_Start(Cronet_UrlRequestPtr self); CRONET_EXPORT -void Cronet_UrlRequest_FollowRedirect(Cronet_UrlRequestPtr self); +Cronet_RESULT Cronet_UrlRequest_FollowRedirect(Cronet_UrlRequestPtr self); CRONET_EXPORT -void Cronet_UrlRequest_Read(Cronet_UrlRequestPtr self, Cronet_BufferPtr buffer); +Cronet_RESULT Cronet_UrlRequest_Read(Cronet_UrlRequestPtr self, + Cronet_BufferPtr buffer); CRONET_EXPORT void Cronet_UrlRequest_Cancel(Cronet_UrlRequestPtr self); CRONET_EXPORT @@ -560,17 +586,18 @@ Cronet_UrlRequestStatusListenerPtr listener); // Concrete interface Cronet_UrlRequest is implemented by Cronet. // The app can implement these for testing / mocking. -typedef void (*Cronet_UrlRequest_InitWithParamsFunc)( +typedef Cronet_RESULT (*Cronet_UrlRequest_InitWithParamsFunc)( Cronet_UrlRequestPtr self, Cronet_EnginePtr engine, CharString url, Cronet_UrlRequestParamsPtr params, Cronet_UrlRequestCallbackPtr callback, Cronet_ExecutorPtr executor); -typedef void (*Cronet_UrlRequest_StartFunc)(Cronet_UrlRequestPtr self); -typedef void (*Cronet_UrlRequest_FollowRedirectFunc)(Cronet_UrlRequestPtr self); -typedef void (*Cronet_UrlRequest_ReadFunc)(Cronet_UrlRequestPtr self, - Cronet_BufferPtr buffer); +typedef Cronet_RESULT (*Cronet_UrlRequest_StartFunc)(Cronet_UrlRequestPtr self); +typedef Cronet_RESULT (*Cronet_UrlRequest_FollowRedirectFunc)( + Cronet_UrlRequestPtr self); +typedef Cronet_RESULT (*Cronet_UrlRequest_ReadFunc)(Cronet_UrlRequestPtr self, + Cronet_BufferPtr buffer); typedef void (*Cronet_UrlRequest_CancelFunc)(Cronet_UrlRequestPtr self); typedef bool (*Cronet_UrlRequest_IsDoneFunc)(Cronet_UrlRequestPtr self); typedef void (*Cronet_UrlRequest_GetStatusFunc)( @@ -588,33 +615,36 @@ Cronet_UrlRequest_GetStatusFunc GetStatusFunc); /////////////////////// -// Struct Cronet_Exception. -CRONET_EXPORT Cronet_ExceptionPtr Cronet_Exception_Create(); -CRONET_EXPORT void Cronet_Exception_Destroy(Cronet_ExceptionPtr self); -// Cronet_Exception setters. +// Struct Cronet_Error. +CRONET_EXPORT Cronet_ErrorPtr Cronet_Error_Create(); +CRONET_EXPORT void Cronet_Error_Destroy(Cronet_ErrorPtr self); +// Cronet_Error setters. CRONET_EXPORT -void Cronet_Exception_set_error_code(Cronet_ExceptionPtr self, - Cronet_Exception_ERROR_CODE error_code); +void Cronet_Error_set_errorCode(Cronet_ErrorPtr self, + Cronet_Error_ERROR_CODE errorCode); CRONET_EXPORT -void Cronet_Exception_set_internal_error_code(Cronet_ExceptionPtr self, - int32_t internal_error_code); +void Cronet_Error_set_message(Cronet_ErrorPtr self, CharString message); CRONET_EXPORT -void Cronet_Exception_set_immediately_retryable(Cronet_ExceptionPtr self, - bool immediately_retryable); +void Cronet_Error_set_internal_error_code(Cronet_ErrorPtr self, + int32_t internal_error_code); CRONET_EXPORT -void Cronet_Exception_set_quic_detailed_error_code( - Cronet_ExceptionPtr self, +void Cronet_Error_set_immediately_retryable(Cronet_ErrorPtr self, + bool immediately_retryable); +CRONET_EXPORT +void Cronet_Error_set_quic_detailed_error_code( + Cronet_ErrorPtr self, int32_t quic_detailed_error_code); -// Cronet_Exception getters. +// Cronet_Error getters. CRONET_EXPORT -Cronet_Exception_ERROR_CODE Cronet_Exception_get_error_code( - Cronet_ExceptionPtr self); +Cronet_Error_ERROR_CODE Cronet_Error_get_errorCode(Cronet_ErrorPtr self); CRONET_EXPORT -int32_t Cronet_Exception_get_internal_error_code(Cronet_ExceptionPtr self); +CharString Cronet_Error_get_message(Cronet_ErrorPtr self); CRONET_EXPORT -bool Cronet_Exception_get_immediately_retryable(Cronet_ExceptionPtr self); +int32_t Cronet_Error_get_internal_error_code(Cronet_ErrorPtr self); CRONET_EXPORT -int32_t Cronet_Exception_get_quic_detailed_error_code(Cronet_ExceptionPtr self); +bool Cronet_Error_get_immediately_retryable(Cronet_ErrorPtr self); +CRONET_EXPORT +int32_t Cronet_Error_get_quic_detailed_error_code(Cronet_ErrorPtr self); /////////////////////// // Struct Cronet_QuicHint. @@ -626,15 +656,15 @@ CRONET_EXPORT void Cronet_QuicHint_set_port(Cronet_QuicHintPtr self, int32_t port); CRONET_EXPORT -void Cronet_QuicHint_set_alternatePort(Cronet_QuicHintPtr self, - int32_t alternatePort); +void Cronet_QuicHint_set_alternate_port(Cronet_QuicHintPtr self, + int32_t alternate_port); // Cronet_QuicHint getters. CRONET_EXPORT CharString Cronet_QuicHint_get_host(Cronet_QuicHintPtr self); CRONET_EXPORT int32_t Cronet_QuicHint_get_port(Cronet_QuicHintPtr self); CRONET_EXPORT -int32_t Cronet_QuicHint_get_alternatePort(Cronet_QuicHintPtr self); +int32_t Cronet_QuicHint_get_alternate_port(Cronet_QuicHintPtr self); /////////////////////// // Struct Cronet_PublicKeyPins. @@ -645,26 +675,27 @@ void Cronet_PublicKeyPins_set_host(Cronet_PublicKeyPinsPtr self, CharString host); CRONET_EXPORT -void Cronet_PublicKeyPins_add_pinsSha256(Cronet_PublicKeyPinsPtr self, - CharString pinsSha256); +void Cronet_PublicKeyPins_add_pins_sha256(Cronet_PublicKeyPinsPtr self, + CharString pins_sha256); CRONET_EXPORT -void Cronet_PublicKeyPins_set_includeSubdomains(Cronet_PublicKeyPinsPtr self, - bool includeSubdomains); +void Cronet_PublicKeyPins_set_include_subdomains(Cronet_PublicKeyPinsPtr self, + bool include_subdomains); CRONET_EXPORT -void Cronet_PublicKeyPins_set_expirationDate(Cronet_PublicKeyPinsPtr self, - int64_t expirationDate); +void Cronet_PublicKeyPins_set_expiration_date(Cronet_PublicKeyPinsPtr self, + int64_t expiration_date); // Cronet_PublicKeyPins getters. CRONET_EXPORT CharString Cronet_PublicKeyPins_get_host(Cronet_PublicKeyPinsPtr self); CRONET_EXPORT -uint32_t Cronet_PublicKeyPins_get_pinsSha256Size(Cronet_PublicKeyPinsPtr self); -CharString Cronet_PublicKeyPins_get_pinsSha256AtIndex( +uint32_t Cronet_PublicKeyPins_get_pins_sha256Size(Cronet_PublicKeyPinsPtr self); +CRONET_EXPORT +CharString Cronet_PublicKeyPins_get_pins_sha256AtIndex( Cronet_PublicKeyPinsPtr self, uint32_t index); CRONET_EXPORT -bool Cronet_PublicKeyPins_get_includeSubdomains(Cronet_PublicKeyPinsPtr self); +bool Cronet_PublicKeyPins_get_include_subdomains(Cronet_PublicKeyPinsPtr self); CRONET_EXPORT -int64_t Cronet_PublicKeyPins_get_expirationDate(Cronet_PublicKeyPinsPtr self); +int64_t Cronet_PublicKeyPins_get_expiration_date(Cronet_PublicKeyPinsPtr self); /////////////////////// // Struct Cronet_EngineParams. @@ -672,83 +703,87 @@ CRONET_EXPORT void Cronet_EngineParams_Destroy(Cronet_EngineParamsPtr self); // Cronet_EngineParams setters. CRONET_EXPORT -void Cronet_EngineParams_set_enableCheckResult(Cronet_EngineParamsPtr self, - bool enableCheckResult); +void Cronet_EngineParams_set_enable_check_result(Cronet_EngineParamsPtr self, + bool enable_check_result); CRONET_EXPORT -void Cronet_EngineParams_set_userAgent(Cronet_EngineParamsPtr self, - CharString userAgent); +void Cronet_EngineParams_set_user_agent(Cronet_EngineParamsPtr self, + CharString user_agent); CRONET_EXPORT -void Cronet_EngineParams_set_acceptLanguage(Cronet_EngineParamsPtr self, - CharString acceptLanguage); +void Cronet_EngineParams_set_accept_language(Cronet_EngineParamsPtr self, + CharString accept_language); CRONET_EXPORT -void Cronet_EngineParams_set_storagePath(Cronet_EngineParamsPtr self, - CharString storagePath); +void Cronet_EngineParams_set_storage_path(Cronet_EngineParamsPtr self, + CharString storage_path); CRONET_EXPORT -void Cronet_EngineParams_set_enableQuic(Cronet_EngineParamsPtr self, - bool enableQuic); +void Cronet_EngineParams_set_enable_quic(Cronet_EngineParamsPtr self, + bool enable_quic); CRONET_EXPORT -void Cronet_EngineParams_set_enableHttp2(Cronet_EngineParamsPtr self, - bool enableHttp2); +void Cronet_EngineParams_set_enable_http2(Cronet_EngineParamsPtr self, + bool enable_http2); CRONET_EXPORT -void Cronet_EngineParams_set_enableBrotli(Cronet_EngineParamsPtr self, - bool enableBrotli); +void Cronet_EngineParams_set_enable_brotli(Cronet_EngineParamsPtr self, + bool enable_brotli); CRONET_EXPORT -void Cronet_EngineParams_set_httpCacheMode( +void Cronet_EngineParams_set_http_cache_mode( Cronet_EngineParamsPtr self, - Cronet_EngineParams_HTTP_CACHE_MODE httpCacheMode); + Cronet_EngineParams_HTTP_CACHE_MODE http_cache_mode); CRONET_EXPORT -void Cronet_EngineParams_set_httpCacheMaxSize(Cronet_EngineParamsPtr self, - int64_t httpCacheMaxSize); +void Cronet_EngineParams_set_http_cache_max_size(Cronet_EngineParamsPtr self, + int64_t http_cache_max_size); CRONET_EXPORT -void Cronet_EngineParams_add_quicHints(Cronet_EngineParamsPtr self, - Cronet_QuicHintPtr quicHints); +void Cronet_EngineParams_add_quic_hints(Cronet_EngineParamsPtr self, + Cronet_QuicHintPtr quic_hints); CRONET_EXPORT -void Cronet_EngineParams_add_publicKeyPins( +void Cronet_EngineParams_add_public_key_pins( Cronet_EngineParamsPtr self, - Cronet_PublicKeyPinsPtr publicKeyPins); + Cronet_PublicKeyPinsPtr public_key_pins); CRONET_EXPORT -void Cronet_EngineParams_set_enablePublicKeyPinningBypassForLocalTrustAnchors( +void Cronet_EngineParams_set_enable_public_key_pinning_bypass_for_local_trust_anchors( Cronet_EngineParamsPtr self, - bool enablePublicKeyPinningBypassForLocalTrustAnchors); + bool enable_public_key_pinning_bypass_for_local_trust_anchors); CRONET_EXPORT -void Cronet_EngineParams_set_experimentalOptions( +void Cronet_EngineParams_set_experimental_options( Cronet_EngineParamsPtr self, - CharString experimentalOptions); + CharString experimental_options); // Cronet_EngineParams getters. CRONET_EXPORT -bool Cronet_EngineParams_get_enableCheckResult(Cronet_EngineParamsPtr self); +bool Cronet_EngineParams_get_enable_check_result(Cronet_EngineParamsPtr self); CRONET_EXPORT -CharString Cronet_EngineParams_get_userAgent(Cronet_EngineParamsPtr self); +CharString Cronet_EngineParams_get_user_agent(Cronet_EngineParamsPtr self); CRONET_EXPORT -CharString Cronet_EngineParams_get_acceptLanguage(Cronet_EngineParamsPtr self); +CharString Cronet_EngineParams_get_accept_language(Cronet_EngineParamsPtr self); CRONET_EXPORT -CharString Cronet_EngineParams_get_storagePath(Cronet_EngineParamsPtr self); +CharString Cronet_EngineParams_get_storage_path(Cronet_EngineParamsPtr self); CRONET_EXPORT -bool Cronet_EngineParams_get_enableQuic(Cronet_EngineParamsPtr self); +bool Cronet_EngineParams_get_enable_quic(Cronet_EngineParamsPtr self); CRONET_EXPORT -bool Cronet_EngineParams_get_enableHttp2(Cronet_EngineParamsPtr self); +bool Cronet_EngineParams_get_enable_http2(Cronet_EngineParamsPtr self); CRONET_EXPORT -bool Cronet_EngineParams_get_enableBrotli(Cronet_EngineParamsPtr self); +bool Cronet_EngineParams_get_enable_brotli(Cronet_EngineParamsPtr self); CRONET_EXPORT -Cronet_EngineParams_HTTP_CACHE_MODE Cronet_EngineParams_get_httpCacheMode( +Cronet_EngineParams_HTTP_CACHE_MODE Cronet_EngineParams_get_http_cache_mode( Cronet_EngineParamsPtr self); CRONET_EXPORT -int64_t Cronet_EngineParams_get_httpCacheMaxSize(Cronet_EngineParamsPtr self); +int64_t Cronet_EngineParams_get_http_cache_max_size( + Cronet_EngineParamsPtr self); CRONET_EXPORT -uint32_t Cronet_EngineParams_get_quicHintsSize(Cronet_EngineParamsPtr self); -Cronet_QuicHintPtr Cronet_EngineParams_get_quicHintsAtIndex( +uint32_t Cronet_EngineParams_get_quic_hintsSize(Cronet_EngineParamsPtr self); +CRONET_EXPORT +Cronet_QuicHintPtr Cronet_EngineParams_get_quic_hintsAtIndex( Cronet_EngineParamsPtr self, uint32_t index); CRONET_EXPORT -uint32_t Cronet_EngineParams_get_publicKeyPinsSize(Cronet_EngineParamsPtr self); -Cronet_PublicKeyPinsPtr Cronet_EngineParams_get_publicKeyPinsAtIndex( +uint32_t Cronet_EngineParams_get_public_key_pinsSize( + Cronet_EngineParamsPtr self); +CRONET_EXPORT +Cronet_PublicKeyPinsPtr Cronet_EngineParams_get_public_key_pinsAtIndex( Cronet_EngineParamsPtr self, uint32_t index); CRONET_EXPORT -bool Cronet_EngineParams_get_enablePublicKeyPinningBypassForLocalTrustAnchors( +bool Cronet_EngineParams_get_enable_public_key_pinning_bypass_for_local_trust_anchors( Cronet_EngineParamsPtr self); CRONET_EXPORT -CharString Cronet_EngineParams_get_experimentalOptions( +CharString Cronet_EngineParams_get_experimental_options( Cronet_EngineParamsPtr self); /////////////////////// @@ -776,63 +811,65 @@ void Cronet_UrlResponseInfo_set_url(Cronet_UrlResponseInfoPtr self, CharString url); CRONET_EXPORT -void Cronet_UrlResponseInfo_add_urlChain(Cronet_UrlResponseInfoPtr self, - CharString urlChain); +void Cronet_UrlResponseInfo_add_url_chain(Cronet_UrlResponseInfoPtr self, + CharString url_chain); CRONET_EXPORT -void Cronet_UrlResponseInfo_set_httpStatusCode(Cronet_UrlResponseInfoPtr self, - int32_t httpStatusCode); +void Cronet_UrlResponseInfo_set_http_status_code(Cronet_UrlResponseInfoPtr self, + int32_t http_status_code); CRONET_EXPORT -void Cronet_UrlResponseInfo_set_httpStatusText(Cronet_UrlResponseInfoPtr self, - CharString httpStatusText); +void Cronet_UrlResponseInfo_set_http_status_text(Cronet_UrlResponseInfoPtr self, + CharString http_status_text); CRONET_EXPORT -void Cronet_UrlResponseInfo_add_allHeadersList( +void Cronet_UrlResponseInfo_add_all_headers_list( Cronet_UrlResponseInfoPtr self, - Cronet_HttpHeaderPtr allHeadersList); + Cronet_HttpHeaderPtr all_headers_list); CRONET_EXPORT -void Cronet_UrlResponseInfo_set_wasCached(Cronet_UrlResponseInfoPtr self, - bool wasCached); +void Cronet_UrlResponseInfo_set_was_cached(Cronet_UrlResponseInfoPtr self, + bool was_cached); CRONET_EXPORT -void Cronet_UrlResponseInfo_set_negotiatedProtocol( +void Cronet_UrlResponseInfo_set_negotiated_protocol( Cronet_UrlResponseInfoPtr self, - CharString negotiatedProtocol); + CharString negotiated_protocol); CRONET_EXPORT -void Cronet_UrlResponseInfo_set_proxyServer(Cronet_UrlResponseInfoPtr self, - CharString proxyServer); +void Cronet_UrlResponseInfo_set_proxy_server(Cronet_UrlResponseInfoPtr self, + CharString proxy_server); CRONET_EXPORT -void Cronet_UrlResponseInfo_set_receivedByteCount( +void Cronet_UrlResponseInfo_set_received_byte_count( Cronet_UrlResponseInfoPtr self, - int64_t receivedByteCount); + int64_t received_byte_count); // Cronet_UrlResponseInfo getters. CRONET_EXPORT CharString Cronet_UrlResponseInfo_get_url(Cronet_UrlResponseInfoPtr self); CRONET_EXPORT -uint32_t Cronet_UrlResponseInfo_get_urlChainSize( +uint32_t Cronet_UrlResponseInfo_get_url_chainSize( Cronet_UrlResponseInfoPtr self); -CharString Cronet_UrlResponseInfo_get_urlChainAtIndex( +CRONET_EXPORT +CharString Cronet_UrlResponseInfo_get_url_chainAtIndex( Cronet_UrlResponseInfoPtr self, uint32_t index); CRONET_EXPORT -int32_t Cronet_UrlResponseInfo_get_httpStatusCode( +int32_t Cronet_UrlResponseInfo_get_http_status_code( Cronet_UrlResponseInfoPtr self); CRONET_EXPORT -CharString Cronet_UrlResponseInfo_get_httpStatusText( +CharString Cronet_UrlResponseInfo_get_http_status_text( Cronet_UrlResponseInfoPtr self); CRONET_EXPORT -uint32_t Cronet_UrlResponseInfo_get_allHeadersListSize( +uint32_t Cronet_UrlResponseInfo_get_all_headers_listSize( Cronet_UrlResponseInfoPtr self); -Cronet_HttpHeaderPtr Cronet_UrlResponseInfo_get_allHeadersListAtIndex( +CRONET_EXPORT +Cronet_HttpHeaderPtr Cronet_UrlResponseInfo_get_all_headers_listAtIndex( Cronet_UrlResponseInfoPtr self, uint32_t index); CRONET_EXPORT -bool Cronet_UrlResponseInfo_get_wasCached(Cronet_UrlResponseInfoPtr self); +bool Cronet_UrlResponseInfo_get_was_cached(Cronet_UrlResponseInfoPtr self); CRONET_EXPORT -CharString Cronet_UrlResponseInfo_get_negotiatedProtocol( +CharString Cronet_UrlResponseInfo_get_negotiated_protocol( Cronet_UrlResponseInfoPtr self); CRONET_EXPORT -CharString Cronet_UrlResponseInfo_get_proxyServer( +CharString Cronet_UrlResponseInfo_get_proxy_server( Cronet_UrlResponseInfoPtr self); CRONET_EXPORT -int64_t Cronet_UrlResponseInfo_get_receivedByteCount( +int64_t Cronet_UrlResponseInfo_get_received_byte_count( Cronet_UrlResponseInfoPtr self); /////////////////////// @@ -842,65 +879,75 @@ Cronet_UrlRequestParamsPtr self); // Cronet_UrlRequestParams setters. CRONET_EXPORT -void Cronet_UrlRequestParams_set_httpMethod(Cronet_UrlRequestParamsPtr self, - CharString httpMethod); +void Cronet_UrlRequestParams_set_http_method(Cronet_UrlRequestParamsPtr self, + CharString http_method); CRONET_EXPORT -void Cronet_UrlRequestParams_add_requestHeaders( +void Cronet_UrlRequestParams_add_request_headers( Cronet_UrlRequestParamsPtr self, - Cronet_HttpHeaderPtr requestHeaders); + Cronet_HttpHeaderPtr request_headers); CRONET_EXPORT -void Cronet_UrlRequestParams_set_disableCache(Cronet_UrlRequestParamsPtr self, - bool disableCache); +void Cronet_UrlRequestParams_set_disable_cache(Cronet_UrlRequestParamsPtr self, + bool disable_cache); CRONET_EXPORT void Cronet_UrlRequestParams_set_priority( Cronet_UrlRequestParamsPtr self, Cronet_UrlRequestParams_REQUEST_PRIORITY priority); CRONET_EXPORT -void Cronet_UrlRequestParams_set_uploadDataProvider( +void Cronet_UrlRequestParams_set_upload_data_provider( Cronet_UrlRequestParamsPtr self, - Cronet_UploadDataProviderPtr uploadDataProvider); + Cronet_UploadDataProviderPtr upload_data_provider); CRONET_EXPORT -void Cronet_UrlRequestParams_set_uploadDataProviderExecutor( +void Cronet_UrlRequestParams_set_upload_data_provider_executor( Cronet_UrlRequestParamsPtr self, - Cronet_ExecutorPtr uploadDataProviderExecutor); + Cronet_ExecutorPtr upload_data_provider_executor); CRONET_EXPORT -void Cronet_UrlRequestParams_set_allowDirectExecutor( +void Cronet_UrlRequestParams_set_allow_direct_executor( Cronet_UrlRequestParamsPtr self, - bool allowDirectExecutor); + bool allow_direct_executor); CRONET_EXPORT void Cronet_UrlRequestParams_add_annotations(Cronet_UrlRequestParamsPtr self, RawDataPtr annotations); // Cronet_UrlRequestParams getters. CRONET_EXPORT -CharString Cronet_UrlRequestParams_get_httpMethod( +CharString Cronet_UrlRequestParams_get_http_method( Cronet_UrlRequestParamsPtr self); CRONET_EXPORT -uint32_t Cronet_UrlRequestParams_get_requestHeadersSize( +uint32_t Cronet_UrlRequestParams_get_request_headersSize( Cronet_UrlRequestParamsPtr self); -Cronet_HttpHeaderPtr Cronet_UrlRequestParams_get_requestHeadersAtIndex( +CRONET_EXPORT +Cronet_HttpHeaderPtr Cronet_UrlRequestParams_get_request_headersAtIndex( Cronet_UrlRequestParamsPtr self, uint32_t index); CRONET_EXPORT -bool Cronet_UrlRequestParams_get_disableCache(Cronet_UrlRequestParamsPtr self); +bool Cronet_UrlRequestParams_get_disable_cache(Cronet_UrlRequestParamsPtr self); CRONET_EXPORT Cronet_UrlRequestParams_REQUEST_PRIORITY Cronet_UrlRequestParams_get_priority( Cronet_UrlRequestParamsPtr self); CRONET_EXPORT -Cronet_UploadDataProviderPtr Cronet_UrlRequestParams_get_uploadDataProvider( +Cronet_UploadDataProviderPtr Cronet_UrlRequestParams_get_upload_data_provider( Cronet_UrlRequestParamsPtr self); CRONET_EXPORT -Cronet_ExecutorPtr Cronet_UrlRequestParams_get_uploadDataProviderExecutor( +Cronet_ExecutorPtr Cronet_UrlRequestParams_get_upload_data_provider_executor( Cronet_UrlRequestParamsPtr self); CRONET_EXPORT -bool Cronet_UrlRequestParams_get_allowDirectExecutor( +bool Cronet_UrlRequestParams_get_allow_direct_executor( Cronet_UrlRequestParamsPtr self); CRONET_EXPORT uint32_t Cronet_UrlRequestParams_get_annotationsSize( Cronet_UrlRequestParamsPtr self); +CRONET_EXPORT RawDataPtr Cronet_UrlRequestParams_get_annotationsAtIndex( Cronet_UrlRequestParamsPtr self, uint32_t index); +/////////////////////// +// Struct Cronet_RequestFinishedInfo. +CRONET_EXPORT Cronet_RequestFinishedInfoPtr Cronet_RequestFinishedInfo_Create(); +CRONET_EXPORT void Cronet_RequestFinishedInfo_Destroy( + Cronet_RequestFinishedInfoPtr self); +// Cronet_RequestFinishedInfo setters. +// Cronet_RequestFinishedInfo getters. + #ifdef __cplusplus } #endif
diff --git a/components/cronet/native/generated/cronet.idl_impl_interface.cc b/components/cronet/native/generated/cronet.idl_impl_interface.cc index 9e89d89..3d075644 100644 --- a/components/cronet/native/generated/cronet.idl_impl_interface.cc +++ b/components/cronet/native/generated/cronet.idl_impl_interface.cc
@@ -288,10 +288,10 @@ } bool Cronet_Engine_StartNetLogToFile(Cronet_EnginePtr self, - CharString fileName, - bool logAll) { + CharString file_name, + bool log_all) { DCHECK(self); - return self->StartNetLogToFile(fileName, logAll); + return self->StartNetLogToFile(file_name, log_all); } void Cronet_Engine_StopNetLog(Cronet_EnginePtr self) { @@ -343,8 +343,8 @@ return StartWithParamsFunc_(this, params); } - bool StartNetLogToFile(CharString fileName, bool logAll) override { - return StartNetLogToFileFunc_(this, fileName, logAll); + bool StartNetLogToFile(CharString file_name, bool log_all) override { + return StartNetLogToFileFunc_(this, file_name, log_all); } void StopNetLog() override { StopNetLogFunc_(this); } @@ -470,9 +470,9 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - CharString newLocationUrl) { + CharString new_location_url) { DCHECK(self); - self->OnRedirectReceived(request, info, newLocationUrl); + self->OnRedirectReceived(request, info, new_location_url); } void Cronet_UrlRequestCallback_OnResponseStarted( @@ -487,9 +487,10 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_BufferPtr buffer) { + Cronet_BufferPtr buffer, + uint64_t bytes_read) { DCHECK(self); - self->OnReadCompleted(request, info, buffer); + self->OnReadCompleted(request, info, buffer, bytes_read); } void Cronet_UrlRequestCallback_OnSucceeded(Cronet_UrlRequestCallbackPtr self, @@ -502,7 +503,7 @@ void Cronet_UrlRequestCallback_OnFailed(Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_ExceptionPtr error) { + Cronet_ErrorPtr error) { DCHECK(self); self->OnFailed(request, info, error); } @@ -543,8 +544,8 @@ protected: void OnRedirectReceived(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - CharString newLocationUrl) override { - OnRedirectReceivedFunc_(this, request, info, newLocationUrl); + CharString new_location_url) override { + OnRedirectReceivedFunc_(this, request, info, new_location_url); } void OnResponseStarted(Cronet_UrlRequestPtr request, @@ -554,8 +555,9 @@ void OnReadCompleted(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_BufferPtr buffer) override { - OnReadCompletedFunc_(this, request, info, buffer); + Cronet_BufferPtr buffer, + uint64_t bytes_read) override { + OnReadCompletedFunc_(this, request, info, buffer, bytes_read); } void OnSucceeded(Cronet_UrlRequestPtr request, @@ -565,7 +567,7 @@ void OnFailed(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_ExceptionPtr error) override { + Cronet_ErrorPtr error) override { OnFailedFunc_(this, request, info, error); } @@ -619,13 +621,13 @@ } void Cronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self, - bool finalChunk) { + bool final_chunk) { DCHECK(self); - self->OnReadSucceeded(finalChunk); + self->OnReadSucceeded(final_chunk); } void Cronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self, - Cronet_ExceptionPtr error) { + Cronet_ErrorPtr error) { DCHECK(self); self->OnReadError(error); } @@ -636,7 +638,7 @@ } void Cronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self, - Cronet_ExceptionPtr error) { + Cronet_ErrorPtr error) { DCHECK(self); self->OnRewindError(error); } @@ -664,17 +666,17 @@ Cronet_UploadDataSinkContext GetContext() override { return context_; } protected: - void OnReadSucceeded(bool finalChunk) override { - OnReadSucceededFunc_(this, finalChunk); + void OnReadSucceeded(bool final_chunk) override { + OnReadSucceededFunc_(this, final_chunk); } - void OnReadError(Cronet_ExceptionPtr error) override { + void OnReadError(Cronet_ErrorPtr error) override { OnReadErrorFunc_(this, error); } void OnRewindSucceded() override { OnRewindSuccededFunc_(this); } - void OnRewindError(Cronet_ExceptionPtr error) override { + void OnRewindError(Cronet_ErrorPtr error) override { OnRewindErrorFunc_(this, error); } @@ -723,16 +725,17 @@ } void Cronet_UploadDataProvider_Read(Cronet_UploadDataProviderPtr self, - Cronet_UploadDataSinkPtr uploadDataSink, + Cronet_UploadDataSinkPtr upload_data_sink, Cronet_BufferPtr buffer) { DCHECK(self); - self->Read(uploadDataSink, buffer); + self->Read(upload_data_sink, buffer); } -void Cronet_UploadDataProvider_Rewind(Cronet_UploadDataProviderPtr self, - Cronet_UploadDataSinkPtr uploadDataSink) { +void Cronet_UploadDataProvider_Rewind( + Cronet_UploadDataProviderPtr self, + Cronet_UploadDataSinkPtr upload_data_sink) { DCHECK(self); - self->Rewind(uploadDataSink); + self->Rewind(upload_data_sink); } void Cronet_UploadDataProvider_Close(Cronet_UploadDataProviderPtr self) { @@ -765,13 +768,13 @@ protected: int64_t GetLength() override { return GetLengthFunc_(this); } - void Read(Cronet_UploadDataSinkPtr uploadDataSink, + void Read(Cronet_UploadDataSinkPtr upload_data_sink, Cronet_BufferPtr buffer) override { - ReadFunc_(this, uploadDataSink, buffer); + ReadFunc_(this, upload_data_sink, buffer); } - void Rewind(Cronet_UploadDataSinkPtr uploadDataSink) override { - RewindFunc_(this, uploadDataSink); + void Rewind(Cronet_UploadDataSinkPtr upload_data_sink) override { + RewindFunc_(this, upload_data_sink); } void Close() override { CloseFunc_(this); } @@ -813,30 +816,31 @@ return self->GetContext(); } -void Cronet_UrlRequest_InitWithParams(Cronet_UrlRequestPtr self, - Cronet_EnginePtr engine, - CharString url, - Cronet_UrlRequestParamsPtr params, - Cronet_UrlRequestCallbackPtr callback, - Cronet_ExecutorPtr executor) { +Cronet_RESULT Cronet_UrlRequest_InitWithParams( + Cronet_UrlRequestPtr self, + Cronet_EnginePtr engine, + CharString url, + Cronet_UrlRequestParamsPtr params, + Cronet_UrlRequestCallbackPtr callback, + Cronet_ExecutorPtr executor) { DCHECK(self); - self->InitWithParams(engine, url, params, callback, executor); + return self->InitWithParams(engine, url, params, callback, executor); } -void Cronet_UrlRequest_Start(Cronet_UrlRequestPtr self) { +Cronet_RESULT Cronet_UrlRequest_Start(Cronet_UrlRequestPtr self) { DCHECK(self); - self->Start(); + return self->Start(); } -void Cronet_UrlRequest_FollowRedirect(Cronet_UrlRequestPtr self) { +Cronet_RESULT Cronet_UrlRequest_FollowRedirect(Cronet_UrlRequestPtr self) { DCHECK(self); - self->FollowRedirect(); + return self->FollowRedirect(); } -void Cronet_UrlRequest_Read(Cronet_UrlRequestPtr self, - Cronet_BufferPtr buffer) { +Cronet_RESULT Cronet_UrlRequest_Read(Cronet_UrlRequestPtr self, + Cronet_BufferPtr buffer) { DCHECK(self); - self->Read(buffer); + return self->Read(buffer); } void Cronet_UrlRequest_Cancel(Cronet_UrlRequestPtr self) { @@ -883,19 +887,21 @@ Cronet_UrlRequestContext GetContext() override { return context_; } protected: - void InitWithParams(Cronet_EnginePtr engine, - CharString url, - Cronet_UrlRequestParamsPtr params, - Cronet_UrlRequestCallbackPtr callback, - Cronet_ExecutorPtr executor) override { - InitWithParamsFunc_(this, engine, url, params, callback, executor); + Cronet_RESULT InitWithParams(Cronet_EnginePtr engine, + CharString url, + Cronet_UrlRequestParamsPtr params, + Cronet_UrlRequestCallbackPtr callback, + Cronet_ExecutorPtr executor) override { + return InitWithParamsFunc_(this, engine, url, params, callback, executor); } - void Start() override { StartFunc_(this); } + Cronet_RESULT Start() override { return StartFunc_(this); } - void FollowRedirect() override { FollowRedirectFunc_(this); } + Cronet_RESULT FollowRedirect() override { return FollowRedirectFunc_(this); } - void Read(Cronet_BufferPtr buffer) override { ReadFunc_(this, buffer); } + Cronet_RESULT Read(Cronet_BufferPtr buffer) override { + return ReadFunc_(this, buffer); + } void Cancel() override { CancelFunc_(this); }
diff --git a/components/cronet/native/generated/cronet.idl_impl_interface.h b/components/cronet/native/generated/cronet.idl_impl_interface.h index f0395f7..cfd50f7 100644 --- a/components/cronet/native/generated/cronet.idl_impl_interface.h +++ b/components/cronet/native/generated/cronet.idl_impl_interface.h
@@ -78,7 +78,7 @@ virtual Cronet_EngineContext GetContext() = 0; virtual Cronet_RESULT StartWithParams(Cronet_EngineParamsPtr params) = 0; - virtual bool StartNetLogToFile(CharString fileName, bool logAll) = 0; + virtual bool StartNetLogToFile(CharString file_name, bool log_all) = 0; virtual void StopNetLog() = 0; virtual Cronet_RESULT Shutdown() = 0; virtual CharString GetVersionString() = 0; @@ -110,17 +110,18 @@ virtual void OnRedirectReceived(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - CharString newLocationUrl) = 0; + CharString new_location_url) = 0; virtual void OnResponseStarted(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info) = 0; virtual void OnReadCompleted(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_BufferPtr buffer) = 0; + Cronet_BufferPtr buffer, + uint64_t bytes_read) = 0; virtual void OnSucceeded(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info) = 0; virtual void OnFailed(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_ExceptionPtr error) = 0; + Cronet_ErrorPtr error) = 0; virtual void OnCanceled(Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info) = 0; @@ -135,10 +136,10 @@ virtual void SetContext(Cronet_UploadDataSinkContext context) = 0; virtual Cronet_UploadDataSinkContext GetContext() = 0; - virtual void OnReadSucceeded(bool finalChunk) = 0; - virtual void OnReadError(Cronet_ExceptionPtr error) = 0; + virtual void OnReadSucceeded(bool final_chunk) = 0; + virtual void OnReadError(Cronet_ErrorPtr error) = 0; virtual void OnRewindSucceded() = 0; - virtual void OnRewindError(Cronet_ExceptionPtr error) = 0; + virtual void OnRewindError(Cronet_ErrorPtr error) = 0; private: DISALLOW_COPY_AND_ASSIGN(Cronet_UploadDataSink); @@ -152,9 +153,9 @@ virtual Cronet_UploadDataProviderContext GetContext() = 0; virtual int64_t GetLength() = 0; - virtual void Read(Cronet_UploadDataSinkPtr uploadDataSink, + virtual void Read(Cronet_UploadDataSinkPtr upload_data_sink, Cronet_BufferPtr buffer) = 0; - virtual void Rewind(Cronet_UploadDataSinkPtr uploadDataSink) = 0; + virtual void Rewind(Cronet_UploadDataSinkPtr upload_data_sink) = 0; virtual void Close() = 0; private: @@ -168,14 +169,14 @@ virtual void SetContext(Cronet_UrlRequestContext context) = 0; virtual Cronet_UrlRequestContext GetContext() = 0; - virtual void InitWithParams(Cronet_EnginePtr engine, - CharString url, - Cronet_UrlRequestParamsPtr params, - Cronet_UrlRequestCallbackPtr callback, - Cronet_ExecutorPtr executor) = 0; - virtual void Start() = 0; - virtual void FollowRedirect() = 0; - virtual void Read(Cronet_BufferPtr buffer) = 0; + virtual Cronet_RESULT InitWithParams(Cronet_EnginePtr engine, + CharString url, + Cronet_UrlRequestParamsPtr params, + Cronet_UrlRequestCallbackPtr callback, + Cronet_ExecutorPtr executor) = 0; + virtual Cronet_RESULT Start() = 0; + virtual Cronet_RESULT FollowRedirect() = 0; + virtual Cronet_RESULT Read(Cronet_BufferPtr buffer) = 0; virtual void Cancel() = 0; virtual bool IsDone() = 0; virtual void GetStatus(Cronet_UrlRequestStatusListenerPtr listener) = 0;
diff --git a/components/cronet/native/generated/cronet.idl_impl_interface_unittest.cc b/components/cronet/native/generated/cronet.idl_impl_interface_unittest.cc index 43f72cb..d5cfccb 100644 --- a/components/cronet/native/generated/cronet.idl_impl_interface_unittest.cc +++ b/components/cronet/native/generated/cronet.idl_impl_interface_unittest.cc
@@ -243,8 +243,8 @@ return static_cast<Cronet_RESULT>(0); } bool TestCronet_Engine_StartNetLogToFile(Cronet_EnginePtr self, - CharString fileName, - bool logAll) { + CharString file_name, + bool log_all) { CHECK(self); Cronet_EngineContext context = Cronet_Engine_GetContext(self); Cronet_EngineTest* test = static_cast<Cronet_EngineTest*>(context); @@ -385,7 +385,7 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - CharString newLocationUrl) { + CharString new_location_url) { CHECK(self); Cronet_UrlRequestCallbackContext context = Cronet_UrlRequestCallback_GetContext(self); @@ -410,7 +410,8 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_BufferPtr buffer) { + Cronet_BufferPtr buffer, + uint64_t bytes_read) { CHECK(self); Cronet_UrlRequestCallbackContext context = Cronet_UrlRequestCallback_GetContext(self); @@ -434,7 +435,7 @@ void TestCronet_UrlRequestCallback_OnFailed(Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_ExceptionPtr error) { + Cronet_ErrorPtr error) { CHECK(self); Cronet_UrlRequestCallbackContext context = Cronet_UrlRequestCallback_GetContext(self); @@ -500,7 +501,7 @@ namespace { // Implementation of Cronet_UploadDataSink methods for testing. void TestCronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self, - bool finalChunk) { + bool final_chunk) { CHECK(self); Cronet_UploadDataSinkContext context = Cronet_UploadDataSink_GetContext(self); Cronet_UploadDataSinkTest* test = @@ -509,7 +510,7 @@ test->OnReadSucceeded_called_ = true; } void TestCronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self, - Cronet_ExceptionPtr error) { + Cronet_ErrorPtr error) { CHECK(self); Cronet_UploadDataSinkContext context = Cronet_UploadDataSink_GetContext(self); Cronet_UploadDataSinkTest* test = @@ -526,7 +527,7 @@ test->OnRewindSucceded_called_ = true; } void TestCronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self, - Cronet_ExceptionPtr error) { + Cronet_ErrorPtr error) { CHECK(self); Cronet_UploadDataSinkContext context = Cronet_UploadDataSink_GetContext(self); Cronet_UploadDataSinkTest* test = @@ -588,9 +589,10 @@ return static_cast<int64_t>(0); } -void TestCronet_UploadDataProvider_Read(Cronet_UploadDataProviderPtr self, - Cronet_UploadDataSinkPtr uploadDataSink, - Cronet_BufferPtr buffer) { +void TestCronet_UploadDataProvider_Read( + Cronet_UploadDataProviderPtr self, + Cronet_UploadDataSinkPtr upload_data_sink, + Cronet_BufferPtr buffer) { CHECK(self); Cronet_UploadDataProviderContext context = Cronet_UploadDataProvider_GetContext(self); @@ -601,7 +603,7 @@ } void TestCronet_UploadDataProvider_Rewind( Cronet_UploadDataProviderPtr self, - Cronet_UploadDataSinkPtr uploadDataSink) { + Cronet_UploadDataSinkPtr upload_data_sink) { CHECK(self); Cronet_UploadDataProviderContext context = Cronet_UploadDataProvider_GetContext(self); @@ -664,39 +666,48 @@ namespace { // Implementation of Cronet_UrlRequest methods for testing. -void TestCronet_UrlRequest_InitWithParams(Cronet_UrlRequestPtr self, - Cronet_EnginePtr engine, - CharString url, - Cronet_UrlRequestParamsPtr params, - Cronet_UrlRequestCallbackPtr callback, - Cronet_ExecutorPtr executor) { +Cronet_RESULT TestCronet_UrlRequest_InitWithParams( + Cronet_UrlRequestPtr self, + Cronet_EnginePtr engine, + CharString url, + Cronet_UrlRequestParamsPtr params, + Cronet_UrlRequestCallbackPtr callback, + Cronet_ExecutorPtr executor) { CHECK(self); Cronet_UrlRequestContext context = Cronet_UrlRequest_GetContext(self); Cronet_UrlRequestTest* test = static_cast<Cronet_UrlRequestTest*>(context); CHECK(test); test->InitWithParams_called_ = true; + + return static_cast<Cronet_RESULT>(0); } -void TestCronet_UrlRequest_Start(Cronet_UrlRequestPtr self) { +Cronet_RESULT TestCronet_UrlRequest_Start(Cronet_UrlRequestPtr self) { CHECK(self); Cronet_UrlRequestContext context = Cronet_UrlRequest_GetContext(self); Cronet_UrlRequestTest* test = static_cast<Cronet_UrlRequestTest*>(context); CHECK(test); test->Start_called_ = true; + + return static_cast<Cronet_RESULT>(0); } -void TestCronet_UrlRequest_FollowRedirect(Cronet_UrlRequestPtr self) { +Cronet_RESULT TestCronet_UrlRequest_FollowRedirect(Cronet_UrlRequestPtr self) { CHECK(self); Cronet_UrlRequestContext context = Cronet_UrlRequest_GetContext(self); Cronet_UrlRequestTest* test = static_cast<Cronet_UrlRequestTest*>(context); CHECK(test); test->FollowRedirect_called_ = true; + + return static_cast<Cronet_RESULT>(0); } -void TestCronet_UrlRequest_Read(Cronet_UrlRequestPtr self, - Cronet_BufferPtr buffer) { +Cronet_RESULT TestCronet_UrlRequest_Read(Cronet_UrlRequestPtr self, + Cronet_BufferPtr buffer) { CHECK(self); Cronet_UrlRequestContext context = Cronet_UrlRequest_GetContext(self); Cronet_UrlRequestTest* test = static_cast<Cronet_UrlRequestTest*>(context); CHECK(test); test->Read_called_ = true; + + return static_cast<Cronet_RESULT>(0); } void TestCronet_UrlRequest_Cancel(Cronet_UrlRequestPtr self) { CHECK(self);
diff --git a/components/cronet/native/generated/cronet.idl_impl_struct.cc b/components/cronet/native/generated/cronet.idl_impl_struct.cc index a57f0118..c5a35611 100644 --- a/components/cronet/native/generated/cronet.idl_impl_struct.cc +++ b/components/cronet/native/generated/cronet.idl_impl_struct.cc
@@ -10,64 +10,72 @@ #include "base/logging.h" -// Struct Cronet_Exception. -Cronet_Exception::Cronet_Exception() {} +// Struct Cronet_Error. +Cronet_Error::Cronet_Error() {} -Cronet_Exception::~Cronet_Exception() {} +Cronet_Error::~Cronet_Error() {} -Cronet_ExceptionPtr Cronet_Exception_Create() { - return new Cronet_Exception(); +Cronet_ErrorPtr Cronet_Error_Create() { + return new Cronet_Error(); } -void Cronet_Exception_Destroy(Cronet_ExceptionPtr self) { +void Cronet_Error_Destroy(Cronet_ErrorPtr self) { delete self; } -// Struct Cronet_Exception setters. -void Cronet_Exception_set_error_code(Cronet_ExceptionPtr self, - Cronet_Exception_ERROR_CODE error_code) { +// Struct Cronet_Error setters. +void Cronet_Error_set_errorCode(Cronet_ErrorPtr self, + Cronet_Error_ERROR_CODE errorCode) { DCHECK(self); - self->error_code = error_code; + self->errorCode = errorCode; } -void Cronet_Exception_set_internal_error_code(Cronet_ExceptionPtr self, - int32_t internal_error_code) { +void Cronet_Error_set_message(Cronet_ErrorPtr self, CharString message) { + DCHECK(self); + self->message = message; +} + +void Cronet_Error_set_internal_error_code(Cronet_ErrorPtr self, + int32_t internal_error_code) { DCHECK(self); self->internal_error_code = internal_error_code; } -void Cronet_Exception_set_immediately_retryable(Cronet_ExceptionPtr self, - bool immediately_retryable) { +void Cronet_Error_set_immediately_retryable(Cronet_ErrorPtr self, + bool immediately_retryable) { DCHECK(self); self->immediately_retryable = immediately_retryable; } -void Cronet_Exception_set_quic_detailed_error_code( - Cronet_ExceptionPtr self, +void Cronet_Error_set_quic_detailed_error_code( + Cronet_ErrorPtr self, int32_t quic_detailed_error_code) { DCHECK(self); self->quic_detailed_error_code = quic_detailed_error_code; } -// Struct Cronet_Exception getters. -Cronet_Exception_ERROR_CODE Cronet_Exception_get_error_code( - Cronet_ExceptionPtr self) { +// Struct Cronet_Error getters. +Cronet_Error_ERROR_CODE Cronet_Error_get_errorCode(Cronet_ErrorPtr self) { DCHECK(self); - return self->error_code; + return self->errorCode; } -int32_t Cronet_Exception_get_internal_error_code(Cronet_ExceptionPtr self) { +CharString Cronet_Error_get_message(Cronet_ErrorPtr self) { + DCHECK(self); + return self->message.c_str(); +} + +int32_t Cronet_Error_get_internal_error_code(Cronet_ErrorPtr self) { DCHECK(self); return self->internal_error_code; } -bool Cronet_Exception_get_immediately_retryable(Cronet_ExceptionPtr self) { +bool Cronet_Error_get_immediately_retryable(Cronet_ErrorPtr self) { DCHECK(self); return self->immediately_retryable; } -int32_t Cronet_Exception_get_quic_detailed_error_code( - Cronet_ExceptionPtr self) { +int32_t Cronet_Error_get_quic_detailed_error_code(Cronet_ErrorPtr self) { DCHECK(self); return self->quic_detailed_error_code; } @@ -96,10 +104,10 @@ self->port = port; } -void Cronet_QuicHint_set_alternatePort(Cronet_QuicHintPtr self, - int32_t alternatePort) { +void Cronet_QuicHint_set_alternate_port(Cronet_QuicHintPtr self, + int32_t alternate_port) { DCHECK(self); - self->alternatePort = alternatePort; + self->alternate_port = alternate_port; } // Struct Cronet_QuicHint getters. @@ -113,9 +121,9 @@ return self->port; } -int32_t Cronet_QuicHint_get_alternatePort(Cronet_QuicHintPtr self) { +int32_t Cronet_QuicHint_get_alternate_port(Cronet_QuicHintPtr self) { DCHECK(self); - return self->alternatePort; + return self->alternate_port; } // Struct Cronet_PublicKeyPins. @@ -138,22 +146,22 @@ self->host = host; } -void Cronet_PublicKeyPins_add_pinsSha256(Cronet_PublicKeyPinsPtr self, - CharString pinsSha256) { +void Cronet_PublicKeyPins_add_pins_sha256(Cronet_PublicKeyPinsPtr self, + CharString pins_sha256) { DCHECK(self); - self->pinsSha256.push_back(pinsSha256); + self->pins_sha256.push_back(pins_sha256); } -void Cronet_PublicKeyPins_set_includeSubdomains(Cronet_PublicKeyPinsPtr self, - bool includeSubdomains) { +void Cronet_PublicKeyPins_set_include_subdomains(Cronet_PublicKeyPinsPtr self, + bool include_subdomains) { DCHECK(self); - self->includeSubdomains = includeSubdomains; + self->include_subdomains = include_subdomains; } -void Cronet_PublicKeyPins_set_expirationDate(Cronet_PublicKeyPinsPtr self, - int64_t expirationDate) { +void Cronet_PublicKeyPins_set_expiration_date(Cronet_PublicKeyPinsPtr self, + int64_t expiration_date) { DCHECK(self); - self->expirationDate = expirationDate; + self->expiration_date = expiration_date; } // Struct Cronet_PublicKeyPins getters. @@ -162,26 +170,27 @@ return self->host.c_str(); } -uint32_t Cronet_PublicKeyPins_get_pinsSha256Size(Cronet_PublicKeyPinsPtr self) { +uint32_t Cronet_PublicKeyPins_get_pins_sha256Size( + Cronet_PublicKeyPinsPtr self) { DCHECK(self); - return self->pinsSha256.size(); + return self->pins_sha256.size(); } -CharString Cronet_PublicKeyPins_get_pinsSha256AtIndex( +CharString Cronet_PublicKeyPins_get_pins_sha256AtIndex( Cronet_PublicKeyPinsPtr self, uint32_t index) { DCHECK(self); - DCHECK(index < self->pinsSha256.size()); - return self->pinsSha256[index].c_str(); + DCHECK(index < self->pins_sha256.size()); + return self->pins_sha256[index].c_str(); } -bool Cronet_PublicKeyPins_get_includeSubdomains(Cronet_PublicKeyPinsPtr self) { +bool Cronet_PublicKeyPins_get_include_subdomains(Cronet_PublicKeyPinsPtr self) { DCHECK(self); - return self->includeSubdomains; + return self->include_subdomains; } -int64_t Cronet_PublicKeyPins_get_expirationDate(Cronet_PublicKeyPinsPtr self) { +int64_t Cronet_PublicKeyPins_get_expiration_date(Cronet_PublicKeyPinsPtr self) { DCHECK(self); - return self->expirationDate; + return self->expiration_date; } // Struct Cronet_EngineParams. @@ -198,173 +207,175 @@ } // Struct Cronet_EngineParams setters. -void Cronet_EngineParams_set_enableCheckResult(Cronet_EngineParamsPtr self, - bool enableCheckResult) { +void Cronet_EngineParams_set_enable_check_result(Cronet_EngineParamsPtr self, + bool enable_check_result) { DCHECK(self); - self->enableCheckResult = enableCheckResult; + self->enable_check_result = enable_check_result; } -void Cronet_EngineParams_set_userAgent(Cronet_EngineParamsPtr self, - CharString userAgent) { +void Cronet_EngineParams_set_user_agent(Cronet_EngineParamsPtr self, + CharString user_agent) { DCHECK(self); - self->userAgent = userAgent; + self->user_agent = user_agent; } -void Cronet_EngineParams_set_acceptLanguage(Cronet_EngineParamsPtr self, - CharString acceptLanguage) { +void Cronet_EngineParams_set_accept_language(Cronet_EngineParamsPtr self, + CharString accept_language) { DCHECK(self); - self->acceptLanguage = acceptLanguage; + self->accept_language = accept_language; } -void Cronet_EngineParams_set_storagePath(Cronet_EngineParamsPtr self, - CharString storagePath) { +void Cronet_EngineParams_set_storage_path(Cronet_EngineParamsPtr self, + CharString storage_path) { DCHECK(self); - self->storagePath = storagePath; + self->storage_path = storage_path; } -void Cronet_EngineParams_set_enableQuic(Cronet_EngineParamsPtr self, - bool enableQuic) { +void Cronet_EngineParams_set_enable_quic(Cronet_EngineParamsPtr self, + bool enable_quic) { DCHECK(self); - self->enableQuic = enableQuic; + self->enable_quic = enable_quic; } -void Cronet_EngineParams_set_enableHttp2(Cronet_EngineParamsPtr self, - bool enableHttp2) { +void Cronet_EngineParams_set_enable_http2(Cronet_EngineParamsPtr self, + bool enable_http2) { DCHECK(self); - self->enableHttp2 = enableHttp2; + self->enable_http2 = enable_http2; } -void Cronet_EngineParams_set_enableBrotli(Cronet_EngineParamsPtr self, - bool enableBrotli) { +void Cronet_EngineParams_set_enable_brotli(Cronet_EngineParamsPtr self, + bool enable_brotli) { DCHECK(self); - self->enableBrotli = enableBrotli; + self->enable_brotli = enable_brotli; } -void Cronet_EngineParams_set_httpCacheMode( +void Cronet_EngineParams_set_http_cache_mode( Cronet_EngineParamsPtr self, - Cronet_EngineParams_HTTP_CACHE_MODE httpCacheMode) { + Cronet_EngineParams_HTTP_CACHE_MODE http_cache_mode) { DCHECK(self); - self->httpCacheMode = httpCacheMode; + self->http_cache_mode = http_cache_mode; } -void Cronet_EngineParams_set_httpCacheMaxSize(Cronet_EngineParamsPtr self, - int64_t httpCacheMaxSize) { +void Cronet_EngineParams_set_http_cache_max_size(Cronet_EngineParamsPtr self, + int64_t http_cache_max_size) { DCHECK(self); - self->httpCacheMaxSize = httpCacheMaxSize; + self->http_cache_max_size = http_cache_max_size; } -void Cronet_EngineParams_add_quicHints(Cronet_EngineParamsPtr self, - Cronet_QuicHintPtr quicHints) { +void Cronet_EngineParams_add_quic_hints(Cronet_EngineParamsPtr self, + Cronet_QuicHintPtr quic_hints) { DCHECK(self); - std::unique_ptr<Cronet_QuicHint> tmp_ptr(quicHints); - self->quicHints.push_back(std::move(tmp_ptr)); + std::unique_ptr<Cronet_QuicHint> tmp_ptr(quic_hints); + self->quic_hints.push_back(std::move(tmp_ptr)); } -void Cronet_EngineParams_add_publicKeyPins( +void Cronet_EngineParams_add_public_key_pins( Cronet_EngineParamsPtr self, - Cronet_PublicKeyPinsPtr publicKeyPins) { + Cronet_PublicKeyPinsPtr public_key_pins) { DCHECK(self); - std::unique_ptr<Cronet_PublicKeyPins> tmp_ptr(publicKeyPins); - self->publicKeyPins.push_back(std::move(tmp_ptr)); + std::unique_ptr<Cronet_PublicKeyPins> tmp_ptr(public_key_pins); + self->public_key_pins.push_back(std::move(tmp_ptr)); } -void Cronet_EngineParams_set_enablePublicKeyPinningBypassForLocalTrustAnchors( +void Cronet_EngineParams_set_enable_public_key_pinning_bypass_for_local_trust_anchors( Cronet_EngineParamsPtr self, - bool enablePublicKeyPinningBypassForLocalTrustAnchors) { + bool enable_public_key_pinning_bypass_for_local_trust_anchors) { DCHECK(self); - self->enablePublicKeyPinningBypassForLocalTrustAnchors = - enablePublicKeyPinningBypassForLocalTrustAnchors; + self->enable_public_key_pinning_bypass_for_local_trust_anchors = + enable_public_key_pinning_bypass_for_local_trust_anchors; } -void Cronet_EngineParams_set_experimentalOptions( +void Cronet_EngineParams_set_experimental_options( Cronet_EngineParamsPtr self, - CharString experimentalOptions) { + CharString experimental_options) { DCHECK(self); - self->experimentalOptions = experimentalOptions; + self->experimental_options = experimental_options; } // Struct Cronet_EngineParams getters. -bool Cronet_EngineParams_get_enableCheckResult(Cronet_EngineParamsPtr self) { +bool Cronet_EngineParams_get_enable_check_result(Cronet_EngineParamsPtr self) { DCHECK(self); - return self->enableCheckResult; + return self->enable_check_result; } -CharString Cronet_EngineParams_get_userAgent(Cronet_EngineParamsPtr self) { +CharString Cronet_EngineParams_get_user_agent(Cronet_EngineParamsPtr self) { DCHECK(self); - return self->userAgent.c_str(); + return self->user_agent.c_str(); } -CharString Cronet_EngineParams_get_acceptLanguage(Cronet_EngineParamsPtr self) { - DCHECK(self); - return self->acceptLanguage.c_str(); -} - -CharString Cronet_EngineParams_get_storagePath(Cronet_EngineParamsPtr self) { - DCHECK(self); - return self->storagePath.c_str(); -} - -bool Cronet_EngineParams_get_enableQuic(Cronet_EngineParamsPtr self) { - DCHECK(self); - return self->enableQuic; -} - -bool Cronet_EngineParams_get_enableHttp2(Cronet_EngineParamsPtr self) { - DCHECK(self); - return self->enableHttp2; -} - -bool Cronet_EngineParams_get_enableBrotli(Cronet_EngineParamsPtr self) { - DCHECK(self); - return self->enableBrotli; -} - -Cronet_EngineParams_HTTP_CACHE_MODE Cronet_EngineParams_get_httpCacheMode( +CharString Cronet_EngineParams_get_accept_language( Cronet_EngineParamsPtr self) { DCHECK(self); - return self->httpCacheMode; + return self->accept_language.c_str(); } -int64_t Cronet_EngineParams_get_httpCacheMaxSize(Cronet_EngineParamsPtr self) { +CharString Cronet_EngineParams_get_storage_path(Cronet_EngineParamsPtr self) { DCHECK(self); - return self->httpCacheMaxSize; + return self->storage_path.c_str(); } -uint32_t Cronet_EngineParams_get_quicHintsSize(Cronet_EngineParamsPtr self) { +bool Cronet_EngineParams_get_enable_quic(Cronet_EngineParamsPtr self) { DCHECK(self); - return self->quicHints.size(); + return self->enable_quic; } -Cronet_QuicHintPtr Cronet_EngineParams_get_quicHintsAtIndex( + +bool Cronet_EngineParams_get_enable_http2(Cronet_EngineParamsPtr self) { + DCHECK(self); + return self->enable_http2; +} + +bool Cronet_EngineParams_get_enable_brotli(Cronet_EngineParamsPtr self) { + DCHECK(self); + return self->enable_brotli; +} + +Cronet_EngineParams_HTTP_CACHE_MODE Cronet_EngineParams_get_http_cache_mode( + Cronet_EngineParamsPtr self) { + DCHECK(self); + return self->http_cache_mode; +} + +int64_t Cronet_EngineParams_get_http_cache_max_size( + Cronet_EngineParamsPtr self) { + DCHECK(self); + return self->http_cache_max_size; +} + +uint32_t Cronet_EngineParams_get_quic_hintsSize(Cronet_EngineParamsPtr self) { + DCHECK(self); + return self->quic_hints.size(); +} +Cronet_QuicHintPtr Cronet_EngineParams_get_quic_hintsAtIndex( Cronet_EngineParamsPtr self, uint32_t index) { DCHECK(self); - DCHECK(index < self->quicHints.size()); - return self->quicHints[index].get(); + DCHECK(index < self->quic_hints.size()); + return self->quic_hints[index].get(); } -uint32_t Cronet_EngineParams_get_publicKeyPinsSize( +uint32_t Cronet_EngineParams_get_public_key_pinsSize( Cronet_EngineParamsPtr self) { DCHECK(self); - return self->publicKeyPins.size(); + return self->public_key_pins.size(); } -Cronet_PublicKeyPinsPtr Cronet_EngineParams_get_publicKeyPinsAtIndex( +Cronet_PublicKeyPinsPtr Cronet_EngineParams_get_public_key_pinsAtIndex( Cronet_EngineParamsPtr self, uint32_t index) { DCHECK(self); - DCHECK(index < self->publicKeyPins.size()); - return self->publicKeyPins[index].get(); + DCHECK(index < self->public_key_pins.size()); + return self->public_key_pins[index].get(); } -bool Cronet_EngineParams_get_enablePublicKeyPinningBypassForLocalTrustAnchors( +bool Cronet_EngineParams_get_enable_public_key_pinning_bypass_for_local_trust_anchors( Cronet_EngineParamsPtr self) { DCHECK(self); - return self->enablePublicKeyPinningBypassForLocalTrustAnchors; + return self->enable_public_key_pinning_bypass_for_local_trust_anchors; } -CharString Cronet_EngineParams_get_experimentalOptions( +CharString Cronet_EngineParams_get_experimental_options( Cronet_EngineParamsPtr self) { DCHECK(self); - return self->experimentalOptions.c_str(); + return self->experimental_options.c_str(); } // Struct Cronet_HttpHeader. @@ -422,56 +433,56 @@ self->url = url; } -void Cronet_UrlResponseInfo_add_urlChain(Cronet_UrlResponseInfoPtr self, - CharString urlChain) { +void Cronet_UrlResponseInfo_add_url_chain(Cronet_UrlResponseInfoPtr self, + CharString url_chain) { DCHECK(self); - self->urlChain.push_back(urlChain); + self->url_chain.push_back(url_chain); } -void Cronet_UrlResponseInfo_set_httpStatusCode(Cronet_UrlResponseInfoPtr self, - int32_t httpStatusCode) { +void Cronet_UrlResponseInfo_set_http_status_code(Cronet_UrlResponseInfoPtr self, + int32_t http_status_code) { DCHECK(self); - self->httpStatusCode = httpStatusCode; + self->http_status_code = http_status_code; } -void Cronet_UrlResponseInfo_set_httpStatusText(Cronet_UrlResponseInfoPtr self, - CharString httpStatusText) { +void Cronet_UrlResponseInfo_set_http_status_text(Cronet_UrlResponseInfoPtr self, + CharString http_status_text) { DCHECK(self); - self->httpStatusText = httpStatusText; + self->http_status_text = http_status_text; } -void Cronet_UrlResponseInfo_add_allHeadersList( +void Cronet_UrlResponseInfo_add_all_headers_list( Cronet_UrlResponseInfoPtr self, - Cronet_HttpHeaderPtr allHeadersList) { + Cronet_HttpHeaderPtr all_headers_list) { DCHECK(self); - std::unique_ptr<Cronet_HttpHeader> tmp_ptr(allHeadersList); - self->allHeadersList.push_back(std::move(tmp_ptr)); + std::unique_ptr<Cronet_HttpHeader> tmp_ptr(all_headers_list); + self->all_headers_list.push_back(std::move(tmp_ptr)); } -void Cronet_UrlResponseInfo_set_wasCached(Cronet_UrlResponseInfoPtr self, - bool wasCached) { +void Cronet_UrlResponseInfo_set_was_cached(Cronet_UrlResponseInfoPtr self, + bool was_cached) { DCHECK(self); - self->wasCached = wasCached; + self->was_cached = was_cached; } -void Cronet_UrlResponseInfo_set_negotiatedProtocol( +void Cronet_UrlResponseInfo_set_negotiated_protocol( Cronet_UrlResponseInfoPtr self, - CharString negotiatedProtocol) { + CharString negotiated_protocol) { DCHECK(self); - self->negotiatedProtocol = negotiatedProtocol; + self->negotiated_protocol = negotiated_protocol; } -void Cronet_UrlResponseInfo_set_proxyServer(Cronet_UrlResponseInfoPtr self, - CharString proxyServer) { +void Cronet_UrlResponseInfo_set_proxy_server(Cronet_UrlResponseInfoPtr self, + CharString proxy_server) { DCHECK(self); - self->proxyServer = proxyServer; + self->proxy_server = proxy_server; } -void Cronet_UrlResponseInfo_set_receivedByteCount( +void Cronet_UrlResponseInfo_set_received_byte_count( Cronet_UrlResponseInfoPtr self, - int64_t receivedByteCount) { + int64_t received_byte_count) { DCHECK(self); - self->receivedByteCount = receivedByteCount; + self->received_byte_count = received_byte_count; } // Struct Cronet_UrlResponseInfo getters. @@ -480,65 +491,65 @@ return self->url.c_str(); } -uint32_t Cronet_UrlResponseInfo_get_urlChainSize( +uint32_t Cronet_UrlResponseInfo_get_url_chainSize( Cronet_UrlResponseInfoPtr self) { DCHECK(self); - return self->urlChain.size(); + return self->url_chain.size(); } -CharString Cronet_UrlResponseInfo_get_urlChainAtIndex( +CharString Cronet_UrlResponseInfo_get_url_chainAtIndex( Cronet_UrlResponseInfoPtr self, uint32_t index) { DCHECK(self); - DCHECK(index < self->urlChain.size()); - return self->urlChain[index].c_str(); + DCHECK(index < self->url_chain.size()); + return self->url_chain[index].c_str(); } -int32_t Cronet_UrlResponseInfo_get_httpStatusCode( +int32_t Cronet_UrlResponseInfo_get_http_status_code( Cronet_UrlResponseInfoPtr self) { DCHECK(self); - return self->httpStatusCode; + return self->http_status_code; } -CharString Cronet_UrlResponseInfo_get_httpStatusText( +CharString Cronet_UrlResponseInfo_get_http_status_text( Cronet_UrlResponseInfoPtr self) { DCHECK(self); - return self->httpStatusText.c_str(); + return self->http_status_text.c_str(); } -uint32_t Cronet_UrlResponseInfo_get_allHeadersListSize( +uint32_t Cronet_UrlResponseInfo_get_all_headers_listSize( Cronet_UrlResponseInfoPtr self) { DCHECK(self); - return self->allHeadersList.size(); + return self->all_headers_list.size(); } -Cronet_HttpHeaderPtr Cronet_UrlResponseInfo_get_allHeadersListAtIndex( +Cronet_HttpHeaderPtr Cronet_UrlResponseInfo_get_all_headers_listAtIndex( Cronet_UrlResponseInfoPtr self, uint32_t index) { DCHECK(self); - DCHECK(index < self->allHeadersList.size()); - return self->allHeadersList[index].get(); + DCHECK(index < self->all_headers_list.size()); + return self->all_headers_list[index].get(); } -bool Cronet_UrlResponseInfo_get_wasCached(Cronet_UrlResponseInfoPtr self) { +bool Cronet_UrlResponseInfo_get_was_cached(Cronet_UrlResponseInfoPtr self) { DCHECK(self); - return self->wasCached; + return self->was_cached; } -CharString Cronet_UrlResponseInfo_get_negotiatedProtocol( +CharString Cronet_UrlResponseInfo_get_negotiated_protocol( Cronet_UrlResponseInfoPtr self) { DCHECK(self); - return self->negotiatedProtocol.c_str(); + return self->negotiated_protocol.c_str(); } -CharString Cronet_UrlResponseInfo_get_proxyServer( +CharString Cronet_UrlResponseInfo_get_proxy_server( Cronet_UrlResponseInfoPtr self) { DCHECK(self); - return self->proxyServer.c_str(); + return self->proxy_server.c_str(); } -int64_t Cronet_UrlResponseInfo_get_receivedByteCount( +int64_t Cronet_UrlResponseInfo_get_received_byte_count( Cronet_UrlResponseInfoPtr self) { DCHECK(self); - return self->receivedByteCount; + return self->received_byte_count; } // Struct Cronet_UrlRequestParams. @@ -555,24 +566,24 @@ } // Struct Cronet_UrlRequestParams setters. -void Cronet_UrlRequestParams_set_httpMethod(Cronet_UrlRequestParamsPtr self, - CharString httpMethod) { +void Cronet_UrlRequestParams_set_http_method(Cronet_UrlRequestParamsPtr self, + CharString http_method) { DCHECK(self); - self->httpMethod = httpMethod; + self->http_method = http_method; } -void Cronet_UrlRequestParams_add_requestHeaders( +void Cronet_UrlRequestParams_add_request_headers( Cronet_UrlRequestParamsPtr self, - Cronet_HttpHeaderPtr requestHeaders) { + Cronet_HttpHeaderPtr request_headers) { DCHECK(self); - std::unique_ptr<Cronet_HttpHeader> tmp_ptr(requestHeaders); - self->requestHeaders.push_back(std::move(tmp_ptr)); + std::unique_ptr<Cronet_HttpHeader> tmp_ptr(request_headers); + self->request_headers.push_back(std::move(tmp_ptr)); } -void Cronet_UrlRequestParams_set_disableCache(Cronet_UrlRequestParamsPtr self, - bool disableCache) { +void Cronet_UrlRequestParams_set_disable_cache(Cronet_UrlRequestParamsPtr self, + bool disable_cache) { DCHECK(self); - self->disableCache = disableCache; + self->disable_cache = disable_cache; } void Cronet_UrlRequestParams_set_priority( @@ -582,25 +593,25 @@ self->priority = priority; } -void Cronet_UrlRequestParams_set_uploadDataProvider( +void Cronet_UrlRequestParams_set_upload_data_provider( Cronet_UrlRequestParamsPtr self, - Cronet_UploadDataProviderPtr uploadDataProvider) { + Cronet_UploadDataProviderPtr upload_data_provider) { DCHECK(self); - self->uploadDataProvider = uploadDataProvider; + self->upload_data_provider = upload_data_provider; } -void Cronet_UrlRequestParams_set_uploadDataProviderExecutor( +void Cronet_UrlRequestParams_set_upload_data_provider_executor( Cronet_UrlRequestParamsPtr self, - Cronet_ExecutorPtr uploadDataProviderExecutor) { + Cronet_ExecutorPtr upload_data_provider_executor) { DCHECK(self); - self->uploadDataProviderExecutor = uploadDataProviderExecutor; + self->upload_data_provider_executor = upload_data_provider_executor; } -void Cronet_UrlRequestParams_set_allowDirectExecutor( +void Cronet_UrlRequestParams_set_allow_direct_executor( Cronet_UrlRequestParamsPtr self, - bool allowDirectExecutor) { + bool allow_direct_executor) { DCHECK(self); - self->allowDirectExecutor = allowDirectExecutor; + self->allow_direct_executor = allow_direct_executor; } void Cronet_UrlRequestParams_add_annotations(Cronet_UrlRequestParamsPtr self, @@ -610,28 +621,29 @@ } // Struct Cronet_UrlRequestParams getters. -CharString Cronet_UrlRequestParams_get_httpMethod( +CharString Cronet_UrlRequestParams_get_http_method( Cronet_UrlRequestParamsPtr self) { DCHECK(self); - return self->httpMethod.c_str(); + return self->http_method.c_str(); } -uint32_t Cronet_UrlRequestParams_get_requestHeadersSize( +uint32_t Cronet_UrlRequestParams_get_request_headersSize( Cronet_UrlRequestParamsPtr self) { DCHECK(self); - return self->requestHeaders.size(); + return self->request_headers.size(); } -Cronet_HttpHeaderPtr Cronet_UrlRequestParams_get_requestHeadersAtIndex( +Cronet_HttpHeaderPtr Cronet_UrlRequestParams_get_request_headersAtIndex( Cronet_UrlRequestParamsPtr self, uint32_t index) { DCHECK(self); - DCHECK(index < self->requestHeaders.size()); - return self->requestHeaders[index].get(); + DCHECK(index < self->request_headers.size()); + return self->request_headers[index].get(); } -bool Cronet_UrlRequestParams_get_disableCache(Cronet_UrlRequestParamsPtr self) { +bool Cronet_UrlRequestParams_get_disable_cache( + Cronet_UrlRequestParamsPtr self) { DCHECK(self); - return self->disableCache; + return self->disable_cache; } Cronet_UrlRequestParams_REQUEST_PRIORITY Cronet_UrlRequestParams_get_priority( @@ -640,22 +652,22 @@ return self->priority; } -Cronet_UploadDataProviderPtr Cronet_UrlRequestParams_get_uploadDataProvider( +Cronet_UploadDataProviderPtr Cronet_UrlRequestParams_get_upload_data_provider( Cronet_UrlRequestParamsPtr self) { DCHECK(self); - return self->uploadDataProvider; + return self->upload_data_provider; } -Cronet_ExecutorPtr Cronet_UrlRequestParams_get_uploadDataProviderExecutor( +Cronet_ExecutorPtr Cronet_UrlRequestParams_get_upload_data_provider_executor( Cronet_UrlRequestParamsPtr self) { DCHECK(self); - return self->uploadDataProviderExecutor; + return self->upload_data_provider_executor; } -bool Cronet_UrlRequestParams_get_allowDirectExecutor( +bool Cronet_UrlRequestParams_get_allow_direct_executor( Cronet_UrlRequestParamsPtr self) { DCHECK(self); - return self->allowDirectExecutor; + return self->allow_direct_executor; } uint32_t Cronet_UrlRequestParams_get_annotationsSize( @@ -670,3 +682,20 @@ DCHECK(index < self->annotations.size()); return self->annotations[index]; } + +// Struct Cronet_RequestFinishedInfo. +Cronet_RequestFinishedInfo::Cronet_RequestFinishedInfo() {} + +Cronet_RequestFinishedInfo::~Cronet_RequestFinishedInfo() {} + +Cronet_RequestFinishedInfoPtr Cronet_RequestFinishedInfo_Create() { + return new Cronet_RequestFinishedInfo(); +} + +void Cronet_RequestFinishedInfo_Destroy(Cronet_RequestFinishedInfoPtr self) { + delete self; +} + +// Struct Cronet_RequestFinishedInfo setters. + +// Struct Cronet_RequestFinishedInfo getters.
diff --git a/components/cronet/native/generated/cronet.idl_impl_struct.h b/components/cronet/native/generated/cronet.idl_impl_struct.h index ab3b7e1..ed6c5537 100644 --- a/components/cronet/native/generated/cronet.idl_impl_struct.h +++ b/components/cronet/native/generated/cronet.idl_impl_struct.h
@@ -15,20 +15,20 @@ #include "base/macros.h" -// Struct Cronet_Exception. -struct Cronet_Exception { +// Struct Cronet_Error. +struct Cronet_Error { public: - Cronet_Exception(); - ~Cronet_Exception(); + Cronet_Error(); + ~Cronet_Error(); - Cronet_Exception_ERROR_CODE error_code = - Cronet_Exception_ERROR_CODE_ERROR_CALLBACK; + Cronet_Error_ERROR_CODE errorCode = Cronet_Error_ERROR_CODE_ERROR_CALLBACK; + std::string message; int32_t internal_error_code = 0; bool immediately_retryable = false; int32_t quic_detailed_error_code = 0; private: - DISALLOW_COPY_AND_ASSIGN(Cronet_Exception); + DISALLOW_COPY_AND_ASSIGN(Cronet_Error); }; // Struct Cronet_QuicHint. @@ -39,7 +39,7 @@ std::string host; int32_t port = 0; - int32_t alternatePort = 0; + int32_t alternate_port = 0; private: DISALLOW_COPY_AND_ASSIGN(Cronet_QuicHint); @@ -52,9 +52,9 @@ ~Cronet_PublicKeyPins(); std::string host; - std::vector<std::string> pinsSha256; - bool includeSubdomains = false; - int64_t expirationDate; + std::vector<std::string> pins_sha256; + bool include_subdomains = false; + int64_t expiration_date; private: DISALLOW_COPY_AND_ASSIGN(Cronet_PublicKeyPins); @@ -66,20 +66,20 @@ Cronet_EngineParams(); ~Cronet_EngineParams(); - bool enableCheckResult = true; - std::string userAgent; - std::string acceptLanguage; - std::string storagePath; - bool enableQuic = false; - bool enableHttp2 = true; - bool enableBrotli = true; - Cronet_EngineParams_HTTP_CACHE_MODE httpCacheMode = + bool enable_check_result = true; + std::string user_agent; + std::string accept_language; + std::string storage_path; + bool enable_quic = false; + bool enable_http2 = true; + bool enable_brotli = true; + Cronet_EngineParams_HTTP_CACHE_MODE http_cache_mode = Cronet_EngineParams_HTTP_CACHE_MODE_DISABLED; - int64_t httpCacheMaxSize = 0; - std::vector<std::unique_ptr<Cronet_QuicHint>> quicHints; - std::vector<std::unique_ptr<Cronet_PublicKeyPins>> publicKeyPins; - bool enablePublicKeyPinningBypassForLocalTrustAnchors = true; - std::string experimentalOptions; + int64_t http_cache_max_size = 0; + std::vector<std::unique_ptr<Cronet_QuicHint>> quic_hints; + std::vector<std::unique_ptr<Cronet_PublicKeyPins>> public_key_pins; + bool enable_public_key_pinning_bypass_for_local_trust_anchors = true; + std::string experimental_options; private: DISALLOW_COPY_AND_ASSIGN(Cronet_EngineParams); @@ -105,14 +105,14 @@ ~Cronet_UrlResponseInfo(); std::string url; - std::vector<std::string> urlChain; - int32_t httpStatusCode; - std::string httpStatusText; - std::vector<std::unique_ptr<Cronet_HttpHeader>> allHeadersList; - bool wasCached; - std::string negotiatedProtocol; - std::string proxyServer; - int64_t receivedByteCount; + std::vector<std::string> url_chain; + int32_t http_status_code; + std::string http_status_text; + std::vector<std::unique_ptr<Cronet_HttpHeader>> all_headers_list; + bool was_cached; + std::string negotiated_protocol; + std::string proxy_server; + int64_t received_byte_count; private: DISALLOW_COPY_AND_ASSIGN(Cronet_UrlResponseInfo); @@ -124,18 +124,28 @@ Cronet_UrlRequestParams(); ~Cronet_UrlRequestParams(); - std::string httpMethod; - std::vector<std::unique_ptr<Cronet_HttpHeader>> requestHeaders; - bool disableCache = false; + std::string http_method; + std::vector<std::unique_ptr<Cronet_HttpHeader>> request_headers; + bool disable_cache = false; Cronet_UrlRequestParams_REQUEST_PRIORITY priority = Cronet_UrlRequestParams_REQUEST_PRIORITY_REQUEST_PRIORITY_MEDIUM; - Cronet_UploadDataProviderPtr uploadDataProvider; - Cronet_ExecutorPtr uploadDataProviderExecutor; - bool allowDirectExecutor = false; + Cronet_UploadDataProviderPtr upload_data_provider; + Cronet_ExecutorPtr upload_data_provider_executor; + bool allow_direct_executor = false; std::vector<RawDataPtr> annotations; private: DISALLOW_COPY_AND_ASSIGN(Cronet_UrlRequestParams); }; +// Struct Cronet_RequestFinishedInfo. +struct Cronet_RequestFinishedInfo { + public: + Cronet_RequestFinishedInfo(); + ~Cronet_RequestFinishedInfo(); + + private: + DISALLOW_COPY_AND_ASSIGN(Cronet_RequestFinishedInfo); +}; + #endif // COMPONENTS_CRONET_NATIVE_GENERATED_CRONET_IDL_IMPL_STRUCT_H_
diff --git a/components/cronet/native/generated/cronet.idl_impl_struct_unittest.cc b/components/cronet/native/generated/cronet.idl_impl_struct_unittest.cc index f255245..c2a426d 100644 --- a/components/cronet/native/generated/cronet.idl_impl_struct_unittest.cc +++ b/components/cronet/native/generated/cronet.idl_impl_struct_unittest.cc
@@ -23,30 +23,32 @@ DISALLOW_COPY_AND_ASSIGN(CronetStructTest); }; -// Test Struct Cronet_Exception setters and getters. -TEST_F(CronetStructTest, TestCronet_Exception) { - Cronet_ExceptionPtr first = Cronet_Exception_Create(); - Cronet_ExceptionPtr second = Cronet_Exception_Create(); +// Test Struct Cronet_Error setters and getters. +TEST_F(CronetStructTest, TestCronet_Error) { + Cronet_ErrorPtr first = Cronet_Error_Create(); + Cronet_ErrorPtr second = Cronet_Error_Create(); // Copy values from |first| to |second|. - Cronet_Exception_set_error_code(second, - Cronet_Exception_get_error_code(first)); - EXPECT_EQ(Cronet_Exception_get_error_code(first), - Cronet_Exception_get_error_code(second)); - Cronet_Exception_set_internal_error_code( - second, Cronet_Exception_get_internal_error_code(first)); - EXPECT_EQ(Cronet_Exception_get_internal_error_code(first), - Cronet_Exception_get_internal_error_code(second)); - Cronet_Exception_set_immediately_retryable( - second, Cronet_Exception_get_immediately_retryable(first)); - EXPECT_EQ(Cronet_Exception_get_immediately_retryable(first), - Cronet_Exception_get_immediately_retryable(second)); - Cronet_Exception_set_quic_detailed_error_code( - second, Cronet_Exception_get_quic_detailed_error_code(first)); - EXPECT_EQ(Cronet_Exception_get_quic_detailed_error_code(first), - Cronet_Exception_get_quic_detailed_error_code(second)); - Cronet_Exception_Destroy(first); - Cronet_Exception_Destroy(second); + Cronet_Error_set_errorCode(second, Cronet_Error_get_errorCode(first)); + EXPECT_EQ(Cronet_Error_get_errorCode(first), + Cronet_Error_get_errorCode(second)); + Cronet_Error_set_message(second, Cronet_Error_get_message(first)); + EXPECT_STREQ(Cronet_Error_get_message(first), + Cronet_Error_get_message(second)); + Cronet_Error_set_internal_error_code( + second, Cronet_Error_get_internal_error_code(first)); + EXPECT_EQ(Cronet_Error_get_internal_error_code(first), + Cronet_Error_get_internal_error_code(second)); + Cronet_Error_set_immediately_retryable( + second, Cronet_Error_get_immediately_retryable(first)); + EXPECT_EQ(Cronet_Error_get_immediately_retryable(first), + Cronet_Error_get_immediately_retryable(second)); + Cronet_Error_set_quic_detailed_error_code( + second, Cronet_Error_get_quic_detailed_error_code(first)); + EXPECT_EQ(Cronet_Error_get_quic_detailed_error_code(first), + Cronet_Error_get_quic_detailed_error_code(second)); + Cronet_Error_Destroy(first); + Cronet_Error_Destroy(second); } // Test Struct Cronet_QuicHint setters and getters. @@ -60,10 +62,10 @@ Cronet_QuicHint_get_host(second)); Cronet_QuicHint_set_port(second, Cronet_QuicHint_get_port(first)); EXPECT_EQ(Cronet_QuicHint_get_port(first), Cronet_QuicHint_get_port(second)); - Cronet_QuicHint_set_alternatePort(second, - Cronet_QuicHint_get_alternatePort(first)); - EXPECT_EQ(Cronet_QuicHint_get_alternatePort(first), - Cronet_QuicHint_get_alternatePort(second)); + Cronet_QuicHint_set_alternate_port(second, + Cronet_QuicHint_get_alternate_port(first)); + EXPECT_EQ(Cronet_QuicHint_get_alternate_port(first), + Cronet_QuicHint_get_alternate_port(second)); Cronet_QuicHint_Destroy(first); Cronet_QuicHint_Destroy(second); } @@ -77,15 +79,15 @@ Cronet_PublicKeyPins_set_host(second, Cronet_PublicKeyPins_get_host(first)); EXPECT_STREQ(Cronet_PublicKeyPins_get_host(first), Cronet_PublicKeyPins_get_host(second)); - // TODO(mef): Test array |pinsSha256|. - Cronet_PublicKeyPins_set_includeSubdomains( - second, Cronet_PublicKeyPins_get_includeSubdomains(first)); - EXPECT_EQ(Cronet_PublicKeyPins_get_includeSubdomains(first), - Cronet_PublicKeyPins_get_includeSubdomains(second)); - Cronet_PublicKeyPins_set_expirationDate( - second, Cronet_PublicKeyPins_get_expirationDate(first)); - EXPECT_EQ(Cronet_PublicKeyPins_get_expirationDate(first), - Cronet_PublicKeyPins_get_expirationDate(second)); + // TODO(mef): Test array |pins_sha256|. + Cronet_PublicKeyPins_set_include_subdomains( + second, Cronet_PublicKeyPins_get_include_subdomains(first)); + EXPECT_EQ(Cronet_PublicKeyPins_get_include_subdomains(first), + Cronet_PublicKeyPins_get_include_subdomains(second)); + Cronet_PublicKeyPins_set_expiration_date( + second, Cronet_PublicKeyPins_get_expiration_date(first)); + EXPECT_EQ(Cronet_PublicKeyPins_get_expiration_date(first), + Cronet_PublicKeyPins_get_expiration_date(second)); Cronet_PublicKeyPins_Destroy(first); Cronet_PublicKeyPins_Destroy(second); } @@ -96,57 +98,57 @@ Cronet_EngineParamsPtr second = Cronet_EngineParams_Create(); // Copy values from |first| to |second|. - Cronet_EngineParams_set_enableCheckResult( - second, Cronet_EngineParams_get_enableCheckResult(first)); - EXPECT_EQ(Cronet_EngineParams_get_enableCheckResult(first), - Cronet_EngineParams_get_enableCheckResult(second)); - Cronet_EngineParams_set_userAgent(second, - Cronet_EngineParams_get_userAgent(first)); - EXPECT_STREQ(Cronet_EngineParams_get_userAgent(first), - Cronet_EngineParams_get_userAgent(second)); - Cronet_EngineParams_set_acceptLanguage( - second, Cronet_EngineParams_get_acceptLanguage(first)); - EXPECT_STREQ(Cronet_EngineParams_get_acceptLanguage(first), - Cronet_EngineParams_get_acceptLanguage(second)); - Cronet_EngineParams_set_storagePath( - second, Cronet_EngineParams_get_storagePath(first)); - EXPECT_STREQ(Cronet_EngineParams_get_storagePath(first), - Cronet_EngineParams_get_storagePath(second)); - Cronet_EngineParams_set_enableQuic(second, - Cronet_EngineParams_get_enableQuic(first)); - EXPECT_EQ(Cronet_EngineParams_get_enableQuic(first), - Cronet_EngineParams_get_enableQuic(second)); - Cronet_EngineParams_set_enableHttp2( - second, Cronet_EngineParams_get_enableHttp2(first)); - EXPECT_EQ(Cronet_EngineParams_get_enableHttp2(first), - Cronet_EngineParams_get_enableHttp2(second)); - Cronet_EngineParams_set_enableBrotli( - second, Cronet_EngineParams_get_enableBrotli(first)); - EXPECT_EQ(Cronet_EngineParams_get_enableBrotli(first), - Cronet_EngineParams_get_enableBrotli(second)); - Cronet_EngineParams_set_httpCacheMode( - second, Cronet_EngineParams_get_httpCacheMode(first)); - EXPECT_EQ(Cronet_EngineParams_get_httpCacheMode(first), - Cronet_EngineParams_get_httpCacheMode(second)); - Cronet_EngineParams_set_httpCacheMaxSize( - second, Cronet_EngineParams_get_httpCacheMaxSize(first)); - EXPECT_EQ(Cronet_EngineParams_get_httpCacheMaxSize(first), - Cronet_EngineParams_get_httpCacheMaxSize(second)); - // TODO(mef): Test array |quicHints|. - // TODO(mef): Test array |publicKeyPins|. - Cronet_EngineParams_set_enablePublicKeyPinningBypassForLocalTrustAnchors( + Cronet_EngineParams_set_enable_check_result( + second, Cronet_EngineParams_get_enable_check_result(first)); + EXPECT_EQ(Cronet_EngineParams_get_enable_check_result(first), + Cronet_EngineParams_get_enable_check_result(second)); + Cronet_EngineParams_set_user_agent(second, + Cronet_EngineParams_get_user_agent(first)); + EXPECT_STREQ(Cronet_EngineParams_get_user_agent(first), + Cronet_EngineParams_get_user_agent(second)); + Cronet_EngineParams_set_accept_language( + second, Cronet_EngineParams_get_accept_language(first)); + EXPECT_STREQ(Cronet_EngineParams_get_accept_language(first), + Cronet_EngineParams_get_accept_language(second)); + Cronet_EngineParams_set_storage_path( + second, Cronet_EngineParams_get_storage_path(first)); + EXPECT_STREQ(Cronet_EngineParams_get_storage_path(first), + Cronet_EngineParams_get_storage_path(second)); + Cronet_EngineParams_set_enable_quic( + second, Cronet_EngineParams_get_enable_quic(first)); + EXPECT_EQ(Cronet_EngineParams_get_enable_quic(first), + Cronet_EngineParams_get_enable_quic(second)); + Cronet_EngineParams_set_enable_http2( + second, Cronet_EngineParams_get_enable_http2(first)); + EXPECT_EQ(Cronet_EngineParams_get_enable_http2(first), + Cronet_EngineParams_get_enable_http2(second)); + Cronet_EngineParams_set_enable_brotli( + second, Cronet_EngineParams_get_enable_brotli(first)); + EXPECT_EQ(Cronet_EngineParams_get_enable_brotli(first), + Cronet_EngineParams_get_enable_brotli(second)); + Cronet_EngineParams_set_http_cache_mode( + second, Cronet_EngineParams_get_http_cache_mode(first)); + EXPECT_EQ(Cronet_EngineParams_get_http_cache_mode(first), + Cronet_EngineParams_get_http_cache_mode(second)); + Cronet_EngineParams_set_http_cache_max_size( + second, Cronet_EngineParams_get_http_cache_max_size(first)); + EXPECT_EQ(Cronet_EngineParams_get_http_cache_max_size(first), + Cronet_EngineParams_get_http_cache_max_size(second)); + // TODO(mef): Test array |quic_hints|. + // TODO(mef): Test array |public_key_pins|. + Cronet_EngineParams_set_enable_public_key_pinning_bypass_for_local_trust_anchors( second, - Cronet_EngineParams_get_enablePublicKeyPinningBypassForLocalTrustAnchors( + Cronet_EngineParams_get_enable_public_key_pinning_bypass_for_local_trust_anchors( first)); EXPECT_EQ( - Cronet_EngineParams_get_enablePublicKeyPinningBypassForLocalTrustAnchors( + Cronet_EngineParams_get_enable_public_key_pinning_bypass_for_local_trust_anchors( first), - Cronet_EngineParams_get_enablePublicKeyPinningBypassForLocalTrustAnchors( + Cronet_EngineParams_get_enable_public_key_pinning_bypass_for_local_trust_anchors( second)); - Cronet_EngineParams_set_experimentalOptions( - second, Cronet_EngineParams_get_experimentalOptions(first)); - EXPECT_STREQ(Cronet_EngineParams_get_experimentalOptions(first), - Cronet_EngineParams_get_experimentalOptions(second)); + Cronet_EngineParams_set_experimental_options( + second, Cronet_EngineParams_get_experimental_options(first)); + EXPECT_STREQ(Cronet_EngineParams_get_experimental_options(first), + Cronet_EngineParams_get_experimental_options(second)); Cronet_EngineParams_Destroy(first); Cronet_EngineParams_Destroy(second); } @@ -176,32 +178,32 @@ Cronet_UrlResponseInfo_set_url(second, Cronet_UrlResponseInfo_get_url(first)); EXPECT_STREQ(Cronet_UrlResponseInfo_get_url(first), Cronet_UrlResponseInfo_get_url(second)); - // TODO(mef): Test array |urlChain|. - Cronet_UrlResponseInfo_set_httpStatusCode( - second, Cronet_UrlResponseInfo_get_httpStatusCode(first)); - EXPECT_EQ(Cronet_UrlResponseInfo_get_httpStatusCode(first), - Cronet_UrlResponseInfo_get_httpStatusCode(second)); - Cronet_UrlResponseInfo_set_httpStatusText( - second, Cronet_UrlResponseInfo_get_httpStatusText(first)); - EXPECT_STREQ(Cronet_UrlResponseInfo_get_httpStatusText(first), - Cronet_UrlResponseInfo_get_httpStatusText(second)); - // TODO(mef): Test array |allHeadersList|. - Cronet_UrlResponseInfo_set_wasCached( - second, Cronet_UrlResponseInfo_get_wasCached(first)); - EXPECT_EQ(Cronet_UrlResponseInfo_get_wasCached(first), - Cronet_UrlResponseInfo_get_wasCached(second)); - Cronet_UrlResponseInfo_set_negotiatedProtocol( - second, Cronet_UrlResponseInfo_get_negotiatedProtocol(first)); - EXPECT_STREQ(Cronet_UrlResponseInfo_get_negotiatedProtocol(first), - Cronet_UrlResponseInfo_get_negotiatedProtocol(second)); - Cronet_UrlResponseInfo_set_proxyServer( - second, Cronet_UrlResponseInfo_get_proxyServer(first)); - EXPECT_STREQ(Cronet_UrlResponseInfo_get_proxyServer(first), - Cronet_UrlResponseInfo_get_proxyServer(second)); - Cronet_UrlResponseInfo_set_receivedByteCount( - second, Cronet_UrlResponseInfo_get_receivedByteCount(first)); - EXPECT_EQ(Cronet_UrlResponseInfo_get_receivedByteCount(first), - Cronet_UrlResponseInfo_get_receivedByteCount(second)); + // TODO(mef): Test array |url_chain|. + Cronet_UrlResponseInfo_set_http_status_code( + second, Cronet_UrlResponseInfo_get_http_status_code(first)); + EXPECT_EQ(Cronet_UrlResponseInfo_get_http_status_code(first), + Cronet_UrlResponseInfo_get_http_status_code(second)); + Cronet_UrlResponseInfo_set_http_status_text( + second, Cronet_UrlResponseInfo_get_http_status_text(first)); + EXPECT_STREQ(Cronet_UrlResponseInfo_get_http_status_text(first), + Cronet_UrlResponseInfo_get_http_status_text(second)); + // TODO(mef): Test array |all_headers_list|. + Cronet_UrlResponseInfo_set_was_cached( + second, Cronet_UrlResponseInfo_get_was_cached(first)); + EXPECT_EQ(Cronet_UrlResponseInfo_get_was_cached(first), + Cronet_UrlResponseInfo_get_was_cached(second)); + Cronet_UrlResponseInfo_set_negotiated_protocol( + second, Cronet_UrlResponseInfo_get_negotiated_protocol(first)); + EXPECT_STREQ(Cronet_UrlResponseInfo_get_negotiated_protocol(first), + Cronet_UrlResponseInfo_get_negotiated_protocol(second)); + Cronet_UrlResponseInfo_set_proxy_server( + second, Cronet_UrlResponseInfo_get_proxy_server(first)); + EXPECT_STREQ(Cronet_UrlResponseInfo_get_proxy_server(first), + Cronet_UrlResponseInfo_get_proxy_server(second)); + Cronet_UrlResponseInfo_set_received_byte_count( + second, Cronet_UrlResponseInfo_get_received_byte_count(first)); + EXPECT_EQ(Cronet_UrlResponseInfo_get_received_byte_count(first), + Cronet_UrlResponseInfo_get_received_byte_count(second)); Cronet_UrlResponseInfo_Destroy(first); Cronet_UrlResponseInfo_Destroy(second); } @@ -212,32 +214,42 @@ Cronet_UrlRequestParamsPtr second = Cronet_UrlRequestParams_Create(); // Copy values from |first| to |second|. - Cronet_UrlRequestParams_set_httpMethod( - second, Cronet_UrlRequestParams_get_httpMethod(first)); - EXPECT_STREQ(Cronet_UrlRequestParams_get_httpMethod(first), - Cronet_UrlRequestParams_get_httpMethod(second)); - // TODO(mef): Test array |requestHeaders|. - Cronet_UrlRequestParams_set_disableCache( - second, Cronet_UrlRequestParams_get_disableCache(first)); - EXPECT_EQ(Cronet_UrlRequestParams_get_disableCache(first), - Cronet_UrlRequestParams_get_disableCache(second)); + Cronet_UrlRequestParams_set_http_method( + second, Cronet_UrlRequestParams_get_http_method(first)); + EXPECT_STREQ(Cronet_UrlRequestParams_get_http_method(first), + Cronet_UrlRequestParams_get_http_method(second)); + // TODO(mef): Test array |request_headers|. + Cronet_UrlRequestParams_set_disable_cache( + second, Cronet_UrlRequestParams_get_disable_cache(first)); + EXPECT_EQ(Cronet_UrlRequestParams_get_disable_cache(first), + Cronet_UrlRequestParams_get_disable_cache(second)); Cronet_UrlRequestParams_set_priority( second, Cronet_UrlRequestParams_get_priority(first)); EXPECT_EQ(Cronet_UrlRequestParams_get_priority(first), Cronet_UrlRequestParams_get_priority(second)); - Cronet_UrlRequestParams_set_uploadDataProvider( - second, Cronet_UrlRequestParams_get_uploadDataProvider(first)); - EXPECT_EQ(Cronet_UrlRequestParams_get_uploadDataProvider(first), - Cronet_UrlRequestParams_get_uploadDataProvider(second)); - Cronet_UrlRequestParams_set_uploadDataProviderExecutor( - second, Cronet_UrlRequestParams_get_uploadDataProviderExecutor(first)); - EXPECT_EQ(Cronet_UrlRequestParams_get_uploadDataProviderExecutor(first), - Cronet_UrlRequestParams_get_uploadDataProviderExecutor(second)); - Cronet_UrlRequestParams_set_allowDirectExecutor( - second, Cronet_UrlRequestParams_get_allowDirectExecutor(first)); - EXPECT_EQ(Cronet_UrlRequestParams_get_allowDirectExecutor(first), - Cronet_UrlRequestParams_get_allowDirectExecutor(second)); + Cronet_UrlRequestParams_set_upload_data_provider( + second, Cronet_UrlRequestParams_get_upload_data_provider(first)); + EXPECT_EQ(Cronet_UrlRequestParams_get_upload_data_provider(first), + Cronet_UrlRequestParams_get_upload_data_provider(second)); + Cronet_UrlRequestParams_set_upload_data_provider_executor( + second, Cronet_UrlRequestParams_get_upload_data_provider_executor(first)); + EXPECT_EQ(Cronet_UrlRequestParams_get_upload_data_provider_executor(first), + Cronet_UrlRequestParams_get_upload_data_provider_executor(second)); + Cronet_UrlRequestParams_set_allow_direct_executor( + second, Cronet_UrlRequestParams_get_allow_direct_executor(first)); + EXPECT_EQ(Cronet_UrlRequestParams_get_allow_direct_executor(first), + Cronet_UrlRequestParams_get_allow_direct_executor(second)); // TODO(mef): Test array |annotations|. Cronet_UrlRequestParams_Destroy(first); Cronet_UrlRequestParams_Destroy(second); } + +// Test Struct Cronet_RequestFinishedInfo setters and getters. +TEST_F(CronetStructTest, TestCronet_RequestFinishedInfo) { + Cronet_RequestFinishedInfoPtr first = Cronet_RequestFinishedInfo_Create(); + Cronet_RequestFinishedInfoPtr second = Cronet_RequestFinishedInfo_Create(); + + // Copy values from |first| to |second|. + Cronet_RequestFinishedInfo_Destroy(first); + Cronet_RequestFinishedInfo_Destroy(second); +}
diff --git a/components/cronet/native/runnables_unittest.cc b/components/cronet/native/runnables_unittest.cc index 67e80cd..8402b95 100644 --- a/components/cronet/native/runnables_unittest.cc +++ b/components/cronet/native/runnables_unittest.cc
@@ -35,7 +35,8 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_BufferPtr buffer); + Cronet_BufferPtr buffer, + uint64_t bytesRead); bool callback_called() const { return callback_called_; } @@ -102,7 +103,8 @@ Cronet_UrlRequestCallbackPtr self, Cronet_UrlRequestPtr request, Cronet_UrlResponseInfoPtr info, - Cronet_BufferPtr buffer) { + Cronet_BufferPtr buffer, + uint64_t bytesRead) { CHECK(self); CHECK(buffer); // Destroy the |buffer|. @@ -182,7 +184,7 @@ Cronet_RunnablePtr runnable = new cronet::OnceClosureRunnable(base::BindOnce( RunnablesTest::UrlRequestCallback_OnReadCompleted, callback, /* request = */ nullptr, - /* response_info = */ nullptr, buffer)); + /* response_info = */ nullptr, buffer, /* bytes_read = */ 0)); Cronet_UrlRequestCallback_SetContext(callback, this); Cronet_Executor_Execute(executor, runnable); scoped_task_environment_.RunUntilIdle();
diff --git a/components/cronet/tools/generators/c_templates/module_c.h.tmpl b/components/cronet/tools/generators/c_templates/module_c.h.tmpl index a66b4e20..3c3bb18 100644 --- a/components/cronet/tools/generators/c_templates/module_c.h.tmpl +++ b/components/cronet/tools/generators/c_templates/module_c.h.tmpl
@@ -162,6 +162,7 @@ {%- set kind = packed_field.field.kind %} {%- if kind|is_array_kind %} uint32_t {{struct_name}}_get_{{packed_field.field.name}}Size({{struct_name}}Ptr self); +{{export_macro}} {{kind.kind|c_wrapper_type}} {{struct_name}}_get_{{packed_field.field.name}}AtIndex({{struct_name}}Ptr self, uint32_t index); {%- else %} {{packed_field.field.kind|c_wrapper_type}} {{struct_name}}_get_{{packed_field.field.name}}({{struct_name}}Ptr self);
diff --git a/components/domain_reliability/util.cc b/components/domain_reliability/util.cc index 18764300..4fb7894 100644 --- a/components/domain_reliability/util.cc +++ b/components/domain_reliability/util.cc
@@ -131,6 +131,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_41: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_42: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_43: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: return "QUIC"; case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS: NOTREACHED();
diff --git a/components/gcm_driver/crypto/gcm_encryption_provider.cc b/components/gcm_driver/crypto/gcm_encryption_provider.cc index 770206e1..5568f7c 100644 --- a/components/gcm_driver/crypto/gcm_encryption_provider.cc +++ b/components/gcm_driver/crypto/gcm_encryption_provider.cc
@@ -61,13 +61,14 @@ void GCMEncryptionProvider::GetEncryptionInfo( const std::string& app_id, const std::string& authorized_entity, - const EncryptionInfoCallback& callback) { + EncryptionInfoCallback callback) { DCHECK(key_store_); - key_store_->GetKeys(app_id, authorized_entity, - false /* fallback_to_empty_authorized_entity */, - base::Bind(&GCMEncryptionProvider::DidGetEncryptionInfo, - weak_ptr_factory_.GetWeakPtr(), app_id, - authorized_entity, callback)); + key_store_->GetKeys( + app_id, authorized_entity, + false /* fallback_to_empty_authorized_entity */, + base::BindOnce(&GCMEncryptionProvider::DidGetEncryptionInfo, + weak_ptr_factory_.GetWeakPtr(), app_id, authorized_entity, + std::move(callback))); } void GCMEncryptionProvider::RemoveEncryptionInfo( @@ -207,42 +208,42 @@ key_store_->GetKeys( app_id, message.sender_id /* authorized_entity */, true /* fallback_to_empty_authorized_entity */, - base::Bind(&GCMEncryptionProvider::DecryptMessageWithKey, - weak_ptr_factory_.GetWeakPtr(), message.collapse_key, - message.sender_id, std::move(salt), std::move(public_key), - record_size, std::move(ciphertext), version, callback)); + base::BindOnce(&GCMEncryptionProvider::DecryptMessageWithKey, + weak_ptr_factory_.GetWeakPtr(), message.collapse_key, + message.sender_id, std::move(salt), std::move(public_key), + record_size, std::move(ciphertext), version, callback)); } void GCMEncryptionProvider::DidGetEncryptionInfo( const std::string& app_id, const std::string& authorized_entity, - const EncryptionInfoCallback& callback, + EncryptionInfoCallback callback, const KeyPair& pair, const std::string& auth_secret) { if (!pair.IsInitialized()) { key_store_->CreateKeys( app_id, authorized_entity, - base::Bind(&GCMEncryptionProvider::DidCreateEncryptionInfo, - weak_ptr_factory_.GetWeakPtr(), callback)); + base::BindOnce(&GCMEncryptionProvider::DidCreateEncryptionInfo, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); return; } DCHECK_EQ(KeyPair::ECDH_P256, pair.type()); - callback.Run(pair.public_key(), auth_secret); + std::move(callback).Run(pair.public_key(), auth_secret); } void GCMEncryptionProvider::DidCreateEncryptionInfo( - const EncryptionInfoCallback& callback, + EncryptionInfoCallback callback, const KeyPair& pair, const std::string& auth_secret) { if (!pair.IsInitialized()) { - callback.Run(std::string() /* p256dh */, - std::string() /* auth_secret */); + std::move(callback).Run(std::string() /* p256dh */, + std::string() /* auth_secret */); return; } DCHECK_EQ(KeyPair::ECDH_P256, pair.type()); - callback.Run(pair.public_key(), auth_secret); + std::move(callback).Run(pair.public_key(), auth_secret); } void GCMEncryptionProvider::DecryptMessageWithKey(
diff --git a/components/gcm_driver/crypto/gcm_encryption_provider.h b/components/gcm_driver/crypto/gcm_encryption_provider.h index 7d65b17e0..386a51c 100644 --- a/components/gcm_driver/crypto/gcm_encryption_provider.h +++ b/components/gcm_driver/crypto/gcm_encryption_provider.h
@@ -34,8 +34,8 @@ public: // Callback to be invoked when the public key and auth secret are available. using EncryptionInfoCallback = - base::Callback<void(const std::string& p256dh, - const std::string& auth_secret)>; + base::OnceCallback<void(const std::string& p256dh, + const std::string& auth_secret)>; // Callback to be invoked when a message may have been decrypted, as indicated // by the |result|. The |message| contains the dispatchable message in success @@ -59,7 +59,7 @@ // "" for non-InstanceID GCM registrations. void GetEncryptionInfo(const std::string& app_id, const std::string& authorized_entity, - const EncryptionInfoCallback& callback); + EncryptionInfoCallback callback); // Removes all encryption information associated with the |app_id| + // |authorized_entity| pair, then invokes |callback|. |authorized_entity| @@ -89,11 +89,11 @@ void DidGetEncryptionInfo(const std::string& app_id, const std::string& authorized_entity, - const EncryptionInfoCallback& callback, + EncryptionInfoCallback callback, const KeyPair& pair, const std::string& auth_secret); - void DidCreateEncryptionInfo(const EncryptionInfoCallback& callback, + void DidCreateEncryptionInfo(EncryptionInfoCallback callback, const KeyPair& pair, const std::string& auth_secret);
diff --git a/components/gcm_driver/crypto/gcm_key_store.cc b/components/gcm_driver/crypto/gcm_key_store.cc index dca5c830..77ee322 100644 --- a/components/gcm_driver/crypto/gcm_key_store.cc +++ b/components/gcm_driver/crypto/gcm_key_store.cc
@@ -10,6 +10,7 @@ #include "base/bind_helpers.h" #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/sequenced_task_runner.h" @@ -65,17 +66,18 @@ void GCMKeyStore::GetKeys(const std::string& app_id, const std::string& authorized_entity, bool fallback_to_empty_authorized_entity, - const KeysCallback& callback) { - LazyInitialize(base::Bind( - &GCMKeyStore::GetKeysAfterInitialize, weak_factory_.GetWeakPtr(), app_id, - authorized_entity, fallback_to_empty_authorized_entity, callback)); + KeysCallback callback) { + LazyInitialize( + base::BindOnce(&GCMKeyStore::GetKeysAfterInitialize, + weak_factory_.GetWeakPtr(), app_id, authorized_entity, + fallback_to_empty_authorized_entity, std::move(callback))); } void GCMKeyStore::GetKeysAfterInitialize( const std::string& app_id, const std::string& authorized_entity, bool fallback_to_empty_authorized_entity, - const KeysCallback& callback) { + KeysCallback callback) { DCHECK(state_ == State::INITIALIZED || state_ == State::FAILED); bool success = false; @@ -88,7 +90,7 @@ inner_iter = inner_map.find(std::string()); if (inner_iter != inner_map.end()) { const KeyPairAndAuthSecret& key_and_auth = inner_iter->second; - callback.Run(key_and_auth.first, key_and_auth.second); + std::move(callback).Run(key_and_auth.first, key_and_auth.second); success = true; } } @@ -96,24 +98,24 @@ UMA_HISTOGRAM_BOOLEAN("GCM.Crypto.GetKeySuccessRate", success); if (!success) - callback.Run(KeyPair(), std::string() /* auth_secret */); + std::move(callback).Run(KeyPair(), std::string() /* auth_secret */); } void GCMKeyStore::CreateKeys(const std::string& app_id, const std::string& authorized_entity, - const KeysCallback& callback) { - LazyInitialize(base::Bind(&GCMKeyStore::CreateKeysAfterInitialize, - weak_factory_.GetWeakPtr(), app_id, - authorized_entity, callback)); + KeysCallback callback) { + LazyInitialize(base::BindOnce(&GCMKeyStore::CreateKeysAfterInitialize, + weak_factory_.GetWeakPtr(), app_id, + authorized_entity, std::move(callback))); } void GCMKeyStore::CreateKeysAfterInitialize( const std::string& app_id, const std::string& authorized_entity, - const KeysCallback& callback) { + KeysCallback callback) { DCHECK(state_ == State::INITIALIZED || state_ == State::FAILED); if (state_ != State::INITIALIZED) { - callback.Run(KeyPair(), std::string() /* auth_secret */); + std::move(callback).Run(KeyPair(), std::string() /* auth_secret */); return; } @@ -134,7 +136,7 @@ if (!CreateP256KeyPair(&private_key, &public_key)) { NOTREACHED() << "Unable to initialize a P-256 key pair."; - callback.Run(KeyPair(), std::string() /* auth_secret */); + std::move(callback).Run(KeyPair(), std::string() /* auth_secret */); return; } @@ -173,13 +175,13 @@ database_->UpdateEntries( std::move(entries_to_save), std::move(keys_to_remove), - base::Bind(&GCMKeyStore::DidStoreKeys, weak_factory_.GetWeakPtr(), *pair, - auth_secret, callback)); + base::BindOnce(&GCMKeyStore::DidStoreKeys, weak_factory_.GetWeakPtr(), + *pair, auth_secret, std::move(callback))); } void GCMKeyStore::DidStoreKeys(const KeyPair& pair, const std::string& auth_secret, - const KeysCallback& callback, + KeysCallback callback, bool success) { UMA_HISTOGRAM_BOOLEAN("GCM.Crypto.CreateKeySuccessRate", success); @@ -189,30 +191,30 @@ // Our cache is now inconsistent. Reject requests until restarted. state_ = State::FAILED; - callback.Run(KeyPair(), std::string() /* auth_secret */); + std::move(callback).Run(KeyPair(), std::string() /* auth_secret */); return; } - callback.Run(pair, auth_secret); + std::move(callback).Run(pair, auth_secret); } void GCMKeyStore::RemoveKeys(const std::string& app_id, const std::string& authorized_entity, - const base::Closure& callback) { - LazyInitialize(base::Bind(&GCMKeyStore::RemoveKeysAfterInitialize, - weak_factory_.GetWeakPtr(), app_id, - authorized_entity, callback)); + base::OnceClosure callback) { + LazyInitialize(base::BindOnce(&GCMKeyStore::RemoveKeysAfterInitialize, + weak_factory_.GetWeakPtr(), app_id, + authorized_entity, std::move(callback))); } void GCMKeyStore::RemoveKeysAfterInitialize( const std::string& app_id, const std::string& authorized_entity, - const base::Closure& callback) { + base::OnceClosure callback) { DCHECK(state_ == State::INITIALIZED || state_ == State::FAILED); const auto& outer_iter = key_data_.find(app_id); if (outer_iter == key_data_.end() || state_ != State::INITIALIZED) { - callback.Run(); + std::move(callback).Run(); return; } @@ -241,19 +243,19 @@ } } if (!had_keys) { - callback.Run(); + std::move(callback).Run(); return; } if (inner_map.empty()) key_data_.erase(app_id); - database_->UpdateEntries(std::move(entries_to_save), - std::move(keys_to_remove), - base::Bind(&GCMKeyStore::DidRemoveKeys, - weak_factory_.GetWeakPtr(), callback)); + database_->UpdateEntries( + std::move(entries_to_save), std::move(keys_to_remove), + base::BindOnce(&GCMKeyStore::DidRemoveKeys, weak_factory_.GetWeakPtr(), + std::move(callback))); } -void GCMKeyStore::DidRemoveKeys(const base::Closure& callback, bool success) { +void GCMKeyStore::DidRemoveKeys(base::OnceClosure callback, bool success) { UMA_HISTOGRAM_BOOLEAN("GCM.Crypto.RemoveKeySuccessRate", success); if (!success) { @@ -263,16 +265,17 @@ state_ = State::FAILED; } - callback.Run(); + std::move(callback).Run(); } -void GCMKeyStore::LazyInitialize(const base::Closure& done_closure) { +void GCMKeyStore::LazyInitialize(base::OnceClosure done_closure) { if (delayed_task_controller_.CanRunTaskWithoutDelay()) { - done_closure.Run(); + std::move(done_closure).Run(); return; } - delayed_task_controller_.AddTask(done_closure); + delayed_task_controller_.AddTask( + base::AdaptCallbackForRepeating(std::move(done_closure))); if (state_ == State::INITIALIZING) return; @@ -284,7 +287,7 @@ database_->Init( kDatabaseUMAClientName, key_store_path_, leveldb_proto::CreateSimpleOptions(), - base::Bind(&GCMKeyStore::DidInitialize, weak_factory_.GetWeakPtr())); + base::BindOnce(&GCMKeyStore::DidInitialize, weak_factory_.GetWeakPtr())); } void GCMKeyStore::DidInitialize(bool success) { @@ -298,7 +301,7 @@ } database_->LoadEntries( - base::Bind(&GCMKeyStore::DidLoadKeys, weak_factory_.GetWeakPtr())); + base::BindOnce(&GCMKeyStore::DidLoadKeys, weak_factory_.GetWeakPtr())); } void GCMKeyStore::DidLoadKeys(
diff --git a/components/gcm_driver/crypto/gcm_key_store.h b/components/gcm_driver/crypto/gcm_key_store.h index f67f594..0141696a3 100644 --- a/components/gcm_driver/crypto/gcm_key_store.h +++ b/components/gcm_driver/crypto/gcm_key_store.h
@@ -39,8 +39,8 @@ // rather than returning the result. Do not rely on the timing of the callbacks. class GCMKeyStore { public: - using KeysCallback = base::Callback<void(const KeyPair& pair, - const std::string& auth_secret)>; + using KeysCallback = base::OnceCallback<void(const KeyPair& pair, + const std::string& auth_secret)>; GCMKeyStore( const base::FilePath& key_store_path, @@ -57,7 +57,7 @@ void GetKeys(const std::string& app_id, const std::string& authorized_entity, bool fallback_to_empty_authorized_entity, - const KeysCallback& callback); + KeysCallback callback); // Creates a new public/private key-pair for the |app_id| + // |authorized_entity| pair, and invokes |callback| when they are available, @@ -67,7 +67,7 @@ // registration and one or more InstanceID tokens is not supported. void CreateKeys(const std::string& app_id, const std::string& authorized_entity, - const KeysCallback& callback); + KeysCallback callback); // Removes the keys associated with the |app_id| + |authorized_entity| pair, // and invokes |callback| when the operation has finished. |authorized_entity| @@ -75,11 +75,11 @@ // all InstanceID tokens, or "" for non-InstanceID GCM registrations. void RemoveKeys(const std::string& app_id, const std::string& authorized_entity, - const base::Closure& callback); + base::OnceClosure callback); private: // Initializes the database if necessary, and runs |done_closure| when done. - void LazyInitialize(const base::Closure& done_closure); + void LazyInitialize(base::OnceClosure done_closure); void DidInitialize(bool success); void DidLoadKeys(bool success, @@ -87,10 +87,10 @@ void DidStoreKeys(const KeyPair& pair, const std::string& auth_secret, - const KeysCallback& callback, + KeysCallback callback, bool success); - void DidRemoveKeys(const base::Closure& callback, bool success); + void DidRemoveKeys(base::OnceClosure callback, bool success); // Private implementations of the API that will be executed when the database // has either been successfully loaded, or failed to load. @@ -98,13 +98,13 @@ void GetKeysAfterInitialize(const std::string& app_id, const std::string& authorized_entity, bool fallback_to_empty_authorized_entity, - const KeysCallback& callback); + KeysCallback callback); void CreateKeysAfterInitialize(const std::string& app_id, const std::string& authorized_entity, - const KeysCallback& callback); + KeysCallback callback); void RemoveKeysAfterInitialize(const std::string& app_id, const std::string& authorized_entity, - const base::Closure& callback); + base::OnceClosure callback); // Path in which the key store database will be saved. base::FilePath key_store_path_;
diff --git a/components/gcm_driver/features.h b/components/gcm_driver/features.h new file mode 100644 index 0000000..f920b6b --- /dev/null +++ b/components/gcm_driver/features.h
@@ -0,0 +1,28 @@ +// Copyright 2018 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_GCM_DRIVER_FEATURES_H +#define COMPONENTS_GCM_DRIVER_FEATURES_H + +#include "base/feature_list.h" +//#include "components/gcm_driver/common/gcm_driver_export.h" + +namespace gcm { + +namespace features { + +extern const base::Feature kInvalidateTokenFeature; +const int kDefaultTokenInvalidationPeriod = 0; +const char kParamNameTokenInvalidationPeriodDays[] = + "token_invalidation_period"; +const char kGroupName[] = "token_validity_data"; + +// The period after which the GCM token becomes stale. +base::TimeDelta GetTokenInvalidationInterval(); + +} // namespace features + +} // namespace gcm + +#endif // COMPONENTS_GCM_DRIVER_FEATURES_H
diff --git a/components/history/core/browser/url_database.cc b/components/history/core/browser/url_database.cc index 1ef2f03f..a60dc9c 100644 --- a/components/history/core/browser/url_database.cc +++ b/components/history/core/browser/url_database.cc
@@ -253,8 +253,9 @@ DCHECK(!enumerator->initialized_); std::string sql("SELECT "); sql.append(kURLRowFields); - sql.append(" FROM urls WHERE last_visit_time >= ? OR visit_count >= ? OR " - "typed_count >= ?"); + sql.append( + " FROM urls WHERE hidden = 0 AND " + "(last_visit_time >= ? OR visit_count >= ? OR typed_count >= ?)"); sql.append( " ORDER BY typed_count DESC, last_visit_time DESC, visit_count " "DESC");
diff --git a/components/history/core/browser/url_database_unittest.cc b/components/history/core/browser/url_database_unittest.cc index 76692a1..a3f7fd6a 100644 --- a/components/history/core/browser/url_database_unittest.cc +++ b/components/history/core/browser/url_database_unittest.cc
@@ -271,6 +271,11 @@ TimeDelta::FromDays(kLowQualityMatchAgeLimitInDays + 1)); EXPECT_TRUE(AddURL(url_no_match_last_visit)); + URLRow url_hidden(GURL("http://www.url_match_higher_typed_count.com/hidden")); + url_hidden.set_typed_count(kLowQualityMatchTypedLimit + 1); + url_hidden.set_hidden(true); + EXPECT_TRUE(AddURL(url_hidden)); + URLDatabase::URLEnumerator history_enum; EXPECT_TRUE(InitURLEnumeratorForSignificant(&history_enum));
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 5287fb4..03291f1 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -103,11 +103,11 @@ ] public_deps = [ - ":call_stack_profile_params", "//third_party/metrics_proto", ] deps = [ + ":call_stack_profile_params", "//base", "//base:base_static", "//components/prefs",
diff --git a/components/metrics/call_stack_profile_metrics_provider.cc b/components/metrics/call_stack_profile_metrics_provider.cc index 078509b..b748a26 100644 --- a/components/metrics/call_stack_profile_metrics_provider.cc +++ b/components/metrics/call_stack_profile_metrics_provider.cc
@@ -558,12 +558,6 @@ CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() { } -StackSamplingProfiler::CompletedCallback -CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcess( - CallStackProfileParams* params) { - return internal::GetProfilerCallback(params); -} - StackSamplingProfiler::CompletedCallback CallStackProfileMetricsProvider:: GetProfilerCallbackForBrowserProcessUIThreadStartup() { return internal::GetProfilerCallback(&g_ui_thread_sampling_params);
diff --git a/components/metrics/call_stack_profile_metrics_provider.h b/components/metrics/call_stack_profile_metrics_provider.h index a6a1ca5..0a5391d 100644 --- a/components/metrics/call_stack_profile_metrics_provider.h +++ b/components/metrics/call_stack_profile_metrics_provider.h
@@ -54,12 +54,6 @@ ~CallStackProfileMetricsProvider() override; // Returns a callback for use with StackSamplingProfiler that sets up - // parameters for general browser process sampling. The callback should be - // immediately passed to the StackSamplingProfiler, and should not be reused. - static base::StackSamplingProfiler::CompletedCallback - GetProfilerCallbackForBrowserProcess(CallStackProfileParams* params); - - // Returns a callback for use with StackSamplingProfiler that sets up // parameters for UI thread of browser process startup sampling. The callback // should be immediately passed to the StackSamplingProfiler, and should not // be reused.
diff --git a/components/metrics/child_call_stack_profile_collector.cc b/components/metrics/child_call_stack_profile_collector.cc index b4a210d0d..09dc6c8 100644 --- a/components/metrics/child_call_stack_profile_collector.cc +++ b/components/metrics/child_call_stack_profile_collector.cc
@@ -55,8 +55,6 @@ DCHECK(retain_profiles_); retain_profiles_ = false; task_runner_ = base::ThreadTaskRunnerHandle::Get(); - // This should only be set one time per child process. - DCHECK(!parent_collector_); parent_collector_ = std::move(parent_collector); if (parent_collector_) { for (ProfilesState& state : profiles_) {
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.cc b/components/offline_pages/core/model/offline_page_model_taskified.cc index e457f9c5..4be74383 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -106,6 +106,13 @@ offline_page.file_size / 1024, 1, 10000, 50); } +void ReportSavedPagesCount(const MultipleOfflinePageItemCallback& callback, + const MultipleOfflinePageItemResult& all_items) { + UMA_HISTOGRAM_COUNTS_10000("OfflinePages.SavedPageCountUponQuery", + all_items.size()); + callback.Run(all_items); +} + } // namespace // static @@ -113,7 +120,7 @@ OfflinePageModelTaskified::kInitialUpgradeSelectionDelay; // static -constexpr base::TimeDelta OfflinePageModelTaskified::kInitializingTaskDelay; +constexpr base::TimeDelta OfflinePageModelTaskified::kMaintenanceTasksDelay; // static constexpr base::TimeDelta OfflinePageModelTaskified::kClearStorageInterval; @@ -130,10 +137,8 @@ task_queue_(this), skip_clearing_original_url_for_testing_(false), weak_ptr_factory_(this) { + DCHECK_LT(kMaintenanceTasksDelay, OfflinePageMetadataStoreSQL::kClosingDelay); CreateArchivesDirectoryIfNeeded(); - PostClearLegacyTemporaryPagesTask(); - PostClearCachedPagesTask(true /* is_initializing */); - PostCheckMetadataConsistencyTask(true /* is_initializing */); // TODO(fgorski): Call from here, when upgrade task is available: // PostSelectItemsMarkedForUpgrade(); } @@ -239,8 +244,10 @@ void OfflinePageModelTaskified::GetAllPages( const MultipleOfflinePageItemCallback& callback) { - auto task = GetPagesTask::CreateTaskMatchingAllPages(store_.get(), callback); + auto task = GetPagesTask::CreateTaskMatchingAllPages( + store_.get(), base::BindRepeating(&ReportSavedPagesCount, callback)); task_queue_.AddTask(std::move(task)); + ScheduleMaintenanceTasks(); } void OfflinePageModelTaskified::GetPageByOfflineId( @@ -420,11 +427,9 @@ if (policy_controller_->GetPolicy(page_attempted.client_id.name_space) .pages_allowed_per_url != kUnlimitedPages) { RemovePagesMatchingUrlAndNamespace(page_attempted); - PostClearCachedPagesTask(false /* is_initializing */); } - } else { - PostClearCachedPagesTask(false /* is_initializing */); } + ScheduleMaintenanceTasks(); } void OfflinePageModelTaskified::OnAddPageDone(const OfflinePageItem& page, @@ -457,53 +462,48 @@ callback.Run(result); } -void OfflinePageModelTaskified::PostClearLegacyTemporaryPagesTask() { +void OfflinePageModelTaskified::ScheduleMaintenanceTasks() { + // If not enough time has passed, don't queue maintenance tasks. + base::Time now = GetCurrentTime(); + if (now - last_maintenance_tasks_schedule_time_ < kClearStorageInterval) + return; + + bool first_run = last_maintenance_tasks_schedule_time_.is_null(); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - base::Bind(&OfflinePageModelTaskified::ClearLegacyTemporaryPages, - weak_ptr_factory_.GetWeakPtr()), - kInitializingTaskDelay); + base::BindOnce(&OfflinePageModelTaskified::RunMaintenanceTasks, + weak_ptr_factory_.GetWeakPtr(), now, first_run), + kMaintenanceTasksDelay); + + last_maintenance_tasks_schedule_time_ = now; } -void OfflinePageModelTaskified::ClearLegacyTemporaryPages() { - // TODO(romax): When we have external directory, adding the support of getting - // 'legacy' directory and replace the persistent one here. - auto task = std::make_unique<ClearLegacyTemporaryPagesTask>( - store_.get(), policy_controller_.get(), - archive_manager_->GetPrivateArchivesDir()); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::PostClearCachedPagesTask(bool is_initializing) { - if (is_initializing) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::Bind(&OfflinePageModelTaskified::PostClearCachedPagesTask, - weak_ptr_factory_.GetWeakPtr(), false), - kInitializingTaskDelay); - return; +void OfflinePageModelTaskified::RunMaintenanceTasks(const base::Time now, + bool first_run) { + // If this is the first run of this session, enqueue the run-once tasks. + if (first_run) { + // TODO(romax): When we have external directory, adding the support of + // getting 'legacy' directory and replace the persistent one here. + // TODO(carlosk): these tasks implementations look very similar so we should + // probably consolidate them all into a single one. + task_queue_.AddTask(std::make_unique<ClearLegacyTemporaryPagesTask>( + store_.get(), policy_controller_.get(), + archive_manager_->GetPrivateArchivesDir())); + task_queue_.AddTask(std::make_unique<TemporaryPagesConsistencyCheckTask>( + store_.get(), policy_controller_.get(), + archive_manager_->GetTemporaryArchivesDir())); + task_queue_.AddTask(std::make_unique<PersistentPagesConsistencyCheckTask>( + store_.get(), policy_controller_.get(), + archive_manager_->GetPrivateArchivesDir())); } - // If not enough time has passed, do not post the task. - if (GetCurrentTime() - last_clear_cached_pages_time_ < - kClearStorageInterval) { - return; - } - - ClearCachedPages(); -} - -void OfflinePageModelTaskified::ClearCachedPages() { - auto task = std::make_unique<ClearStorageTask>( - store_.get(), archive_manager_.get(), policy_controller_.get(), - GetCurrentTime(), + task_queue_.AddTask(std::make_unique<ClearStorageTask>( + store_.get(), archive_manager_.get(), policy_controller_.get(), now, base::BindOnce(&OfflinePageModelTaskified::OnClearCachedPagesDone, - weak_ptr_factory_.GetWeakPtr(), GetCurrentTime())); - task_queue_.AddTask(std::move(task)); + weak_ptr_factory_.GetWeakPtr()))); } void OfflinePageModelTaskified::OnClearCachedPagesDone( - base::Time start_time, size_t deleted_page_count, ClearStorageResult result) { UMA_HISTOGRAM_ENUMERATION("OfflinePages.ClearTemporaryPages.Result", result, @@ -512,36 +512,6 @@ UMA_HISTOGRAM_COUNTS("OfflinePages.ClearTemporaryPages.BatchSize", deleted_page_count); } - last_clear_cached_pages_time_ = start_time; -} - -void OfflinePageModelTaskified::PostCheckMetadataConsistencyTask( - bool is_initializing) { - if (is_initializing) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::Bind(&OfflinePageModelTaskified::PostCheckMetadataConsistencyTask, - weak_ptr_factory_.GetWeakPtr(), false), - kInitializingTaskDelay); - return; - } - - CheckTemporaryPagesConsistency(); - CheckPersistentPagesConsistency(); -} - -void OfflinePageModelTaskified::CheckTemporaryPagesConsistency() { - auto task = std::make_unique<TemporaryPagesConsistencyCheckTask>( - store_.get(), policy_controller_.get(), - archive_manager_->GetTemporaryArchivesDir()); - task_queue_.AddTask(std::move(task)); -} - -void OfflinePageModelTaskified::CheckPersistentPagesConsistency() { - auto task = std::make_unique<PersistentPagesConsistencyCheckTask>( - store_.get(), policy_controller_.get(), - archive_manager_->GetPrivateArchivesDir()); - task_queue_.AddTask(std::move(task)); } void OfflinePageModelTaskified::PostSelectItemsMarkedForUpgrade() {
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.h b/components/offline_pages/core/model/offline_page_model_taskified.h index 70d7775..184c2130 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified.h +++ b/components/offline_pages/core/model/offline_page_model_taskified.h
@@ -50,18 +50,16 @@ public TaskQueue::Delegate { public: // Initial delay after which a list of items for upgrade will be generated. - // TODO(fgorski): We need to measure the cost of opening and closing the DB, - // before we split |kInitializingTaskDelay| and - // |kInitialUpgradeSelectionDelay| further apart, than 20 seconds. static constexpr base::TimeDelta kInitialUpgradeSelectionDelay = base::TimeDelta::FromSeconds(45); - // Initial delay of other tasks triggered at the startup. - static constexpr base::TimeDelta kInitializingTaskDelay = - base::TimeDelta::FromSeconds(30); + // Delay between the scheduling and actual running of maintenance tasks. To + // not cause the re-opening of the metadata store this delay should be kept + // smaller than OfflinePageMetadataStoreSQL::kClosingDelay. + static constexpr base::TimeDelta kMaintenanceTasksDelay = + base::TimeDelta::FromSeconds(10); - // The time that the storage cleanup will be triggered again since the last - // one. + // Minimum delay between runs of maintenance tasks during a Chrome session. static constexpr base::TimeDelta kClearStorageInterval = base::TimeDelta::FromMinutes(30); @@ -174,20 +172,13 @@ DeletePageResult result, const std::vector<OfflinePageModel::DeletedPageInfo>& infos); - // Methods for clearing temporary pages. - void PostClearLegacyTemporaryPagesTask(); - void ClearLegacyTemporaryPages(); - void PostClearCachedPagesTask(bool is_initializing); - void ClearCachedPages(); - void OnClearCachedPagesDone(base::Time start_time, - size_t deleted_page_count, + // Methods for clearing temporary pages and performing consistency checks. The + // latter are executed only once per Chrome session. + void ScheduleMaintenanceTasks(); + void RunMaintenanceTasks(const base::Time now, bool first_run); + void OnClearCachedPagesDone(size_t deleted_page_count, ClearStorageTask::ClearStorageResult result); - // Methods for consistency check. - void PostCheckMetadataConsistencyTask(bool is_initializing); - void CheckTemporaryPagesConsistency(); - void CheckPersistentPagesConsistency(); - // Method for upgrade to public storage. void PostSelectItemsMarkedForUpgrade(); void SelectItemsMarkedForUpgrade(); @@ -226,9 +217,9 @@ // The task queue used for executing various tasks. TaskQueue task_queue_; - // Time of when the most recent cached pages clearing happened. The value will - // not persist across Chrome restarts. - base::Time last_clear_cached_pages_time_; + // The last scheduling timestamp of the model maintenance tasks that took + // place during the current Chrome session. + base::Time last_maintenance_tasks_schedule_time_; // For testing only. // This value will be affecting the CreateArchiveTasks that are created by the
diff --git a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc index dde297a..4f9931e 100644 --- a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc +++ b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
@@ -148,8 +148,8 @@ const OfflinePageModel::DeletedPageInfo& last_deleted_page_info() { return last_deleted_page_info_; } - base::Time last_clear_page_time() { - return model_->last_clear_cached_pages_time_; + base::Time last_maintenance_tasks_schedule_time() { + return model_->last_maintenance_tasks_schedule_time_; } private: @@ -743,6 +743,9 @@ EXPECT_TRUE(task_queue()->HasRunningTask()); PumpLoop(); + + histogram_tester()->ExpectUniqueSample("OfflinePages.SavedPageCountUponQuery", + 0, 1); } // TODO(romax): remove these 'indicators for newly added tests' when migration @@ -1234,21 +1237,19 @@ EXPECT_CALL(callback, Run(UnorderedElementsAre(page1, page2))); model()->GetAllPages(callback.Get()); PumpLoop(); + + histogram_tester()->ExpectUniqueSample("OfflinePages.SavedPageCountUponQuery", + 2, 1); } // This test is affected by https://crbug.com/725685, which only affects windows // platform. #if defined(OS_WIN) -#define MAYBE_StartUp_ConsistencyCheckExecuted \ - DISABLED_StartUp_ConsistencyCheckExecuted +#define MAYBE_ConsistencyCheckExecuted DISABLED_ConsistencyCheckExecuted #else -#define MAYBE_StartUp_ConsistencyCheckExecuted StartUp_ConsistencyCheckExecuted +#define MAYBE_ConsistencyCheckExecuted ConsistencyCheckExecuted #endif -TEST_F(OfflinePageModelTaskifiedTest, MAYBE_StartUp_ConsistencyCheckExecuted) { - // Rebuild the store so that we can insert pages before the model constructs. - ResetModel(); - BuildStore(); - +TEST_F(OfflinePageModelTaskifiedTest, MAYBE_ConsistencyCheckExecuted) { // Insert temporary pages page_generator()->SetArchiveDirectory(temporary_dir_path()); page_generator()->SetNamespace(kDefaultNamespace); @@ -1282,10 +1283,14 @@ EXPECT_EQ(3UL, test_utils::GetFileCountInDirectory(private_archive_dir_path())); - // Rebuild the model in order to trigger consistency check. - BuildModel(); + // Execute GetAllPages and move the clock forward to cover the delay, in order + // to trigger consistency checks. + base::MockCallback<MultipleOfflinePageItemCallback> callback; + model()->GetAllPages(callback.Get()); task_runner()->FastForwardBy( - OfflinePageModelTaskified::kInitializingTaskDelay); + OfflinePageModelTaskified::kMaintenanceTasksDelay + + base::TimeDelta::FromMilliseconds(1)); + PumpLoop(); EXPECT_EQ(1LL, store_test_util()->GetPageCount()); EXPECT_EQ(0UL, test_utils::GetFileCountInDirectory(temporary_dir_path())); @@ -1294,38 +1299,64 @@ } TEST_F(OfflinePageModelTaskifiedTest, ClearStorage) { - // Rebuilding store and model in order to set clock before executing the clear - // storage during model initialization so that we can check the time. - ResetModel(); - BuildStore(); - BuildModel(); - + // The ClearStorage task should not be executed based on time delays after + // launch (aka the model being built). + task_runner()->FastForwardBy(base::TimeDelta::FromDays(1)); PumpLoop(); - // The clear storage task will be delayed on initialization. - EXPECT_EQ(base::Time(), last_clear_page_time()); + EXPECT_EQ(base::Time(), last_maintenance_tasks_schedule_time()); - // 5 minutes passed and the last clear page time should be - // |now - 5mins + 30seconds| since the clear page will be triggered with a 30 - // seconds delay. The delay is a hard-coded value in the model. - const base::TimeDelta short_delta = base::TimeDelta::FromMinutes(5); - task_runner()->FastForwardBy(short_delta); - auto archiver = BuildArchiver(kTestUrl, ArchiverResult::SUCCESSFULLY_CREATED); - int64_t offline_id = SavePageWithExpectedResult( - kTestUrl, kTestClientId1, kTestUrl2, kEmptyRequestOrigin, - std::move(archiver), SavePageResult::SUCCESS); + // GetAllPages should schedule a delayed task that will eventually run + // ClearStorage. + base::MockCallback<MultipleOfflinePageItemCallback> callback; + model()->GetAllPages(callback.Get()); PumpLoop(); - EXPECT_EQ( - task_runner()->Now() - short_delta + base::TimeDelta::FromSeconds(30), - last_clear_page_time()); + EXPECT_EQ(task_runner()->Now(), last_maintenance_tasks_schedule_time()); + base::Time last_scheduling_time = task_runner()->Now(); + // Confirm no runs so far. + histogram_tester()->ExpectTotalCount( + "OfflinePages.ClearTemporaryPages.Result", 0); + // After the delay (plus 1 millisecond just in case) ClearStorage should be + // enqueued and executed. + const base::TimeDelta run_delay = + OfflinePageModelTaskified::kMaintenanceTasksDelay + + base::TimeDelta::FromMilliseconds(1); + task_runner()->FastForwardBy(run_delay); + PumpLoop(); + EXPECT_EQ(last_scheduling_time, last_maintenance_tasks_schedule_time()); + + // Calling GetAllPages after only half of the enforced interval between + // ClearStorage runs should not schedule ClearStorage. + // Note: The previous elapsed delay is discounted from the clock advance here. task_runner()->FastForwardBy( - OfflinePageModelTaskified::kClearStorageInterval); - archiver = BuildArchiver(kTestUrl, ArchiverResult::SUCCESSFULLY_CREATED); - offline_id = SavePageWithExpectedResult( - kTestUrl, kTestClientId1, kTestUrl2, kEmptyRequestOrigin, - std::move(archiver), SavePageResult::SUCCESS); + OfflinePageModelTaskified::kClearStorageInterval / 2 - run_delay); + ASSERT_GT(task_runner()->Now(), last_scheduling_time); + model()->GetAllPages(callback.Get()); + // And advance the delay too. + task_runner()->FastForwardBy(run_delay); PumpLoop(); - EXPECT_EQ(task_runner()->Now(), last_clear_page_time()); + EXPECT_EQ(last_scheduling_time, last_maintenance_tasks_schedule_time()); + // Confirm a single run happened so far. + histogram_tester()->ExpectUniqueSample( + "OfflinePages.ClearTemporaryPages.Result", + static_cast<int>(ClearStorageResult::UNNECESSARY), 1); + + // Forwarding by the full interval (plus 1 second just in case) should allow + // the task to be enqueued again. + task_runner()->FastForwardBy( + OfflinePageModelTaskified::kClearStorageInterval / 2 + + base::TimeDelta::FromSeconds(1)); + // Saving a page should also immediately enqueue the ClearStorage task. + auto archiver = BuildArchiver(kTestUrl, ArchiverResult::SUCCESSFULLY_CREATED); + SavePageWithExpectedResult(kTestUrl, kTestClientId1, kTestUrl2, + kEmptyRequestOrigin, std::move(archiver), + SavePageResult::SUCCESS); + last_scheduling_time = task_runner()->Now(); + // Advance the delay again. + task_runner()->FastForwardBy(run_delay); + PumpLoop(); + EXPECT_EQ(last_scheduling_time, last_maintenance_tasks_schedule_time()); + // Confirm that two runs happened. histogram_tester()->ExpectUniqueSample( "OfflinePages.ClearTemporaryPages.Result", static_cast<int>(ClearStorageResult::UNNECESSARY), 2);
diff --git a/components/offline_pages/core/model/persistent_pages_consistency_check_task.cc b/components/offline_pages/core/model/persistent_pages_consistency_check_task.cc index 2d25774..45395d7 100644 --- a/components/offline_pages/core/model/persistent_pages_consistency_check_task.cc +++ b/components/offline_pages/core/model/persistent_pages_consistency_check_task.cc
@@ -117,14 +117,14 @@ // faster matching later. persistent_page_info_paths.insert(page_info.file_path); } - // Try to delete the pages by offline ids collected above. - // If there's any database related errors, the function will return false, - // and the database operations will be rolled back since the transaction will - // not be committed. - if (!DeletePagesByOfflineIds(offline_ids_to_delete, db)) - return SyncOperationResult::DB_OPERATION_ERROR; if (offline_ids_to_delete.size() > 0) { + // Try to delete the pages by offline ids collected above. If there's any + // database related errors, the function will return false, and the database + // operations will be rolled back since the transaction will not be + // committed. + if (!DeletePagesByOfflineIds(offline_ids_to_delete, db)) + return SyncOperationResult::DB_OPERATION_ERROR; UMA_HISTOGRAM_COUNTS( "OfflinePages.ConsistencyCheck.Persistent.PagesMissingArchiveFileCount", static_cast<int32_t>(offline_ids_to_delete.size())); @@ -145,14 +145,13 @@ } if (files_to_delete.size() > 0) { + if (!DeleteFiles(files_to_delete)) + return SyncOperationResult::FILE_OPERATION_ERROR; UMA_HISTOGRAM_COUNTS( "OfflinePages.ConsistencyCheck.Persistent.PagesMissingDbEntryCount", static_cast<int32_t>(files_to_delete.size())); } - if (!DeleteFiles(files_to_delete)) - return SyncOperationResult::FILE_OPERATION_ERROR; - return SyncOperationResult::SUCCESS; }
diff --git a/components/offline_pages/core/model/temporary_pages_consistency_check_task.cc b/components/offline_pages/core/model/temporary_pages_consistency_check_task.cc index 21e04f9..99e274b 100644 --- a/components/offline_pages/core/model/temporary_pages_consistency_check_task.cc +++ b/components/offline_pages/core/model/temporary_pages_consistency_check_task.cc
@@ -118,14 +118,14 @@ // faster matching later. temp_page_info_paths.insert(page_info.file_path); } - // Try to delete the pages by offline ids collected above. - // If there's any database related errors, the function will return false, - // and the database operations will be rolled back since the transaction will - // not be committed. - if (!DeletePagesByOfflineIds(offline_ids_to_delete, db)) - return SyncOperationResult::DB_OPERATION_ERROR; if (offline_ids_to_delete.size() > 0) { + // Try to delete the pages by offline ids collected above. If there's any + // database related errors, the function will return false, and the database + // operations will be rolled back since the transaction will not be + // committed. + if (!DeletePagesByOfflineIds(offline_ids_to_delete, db)) + return SyncOperationResult::DB_OPERATION_ERROR; UMA_HISTOGRAM_COUNTS( "OfflinePages.ConsistencyCheck.Temporary.PagesMissingArchiveFileCount", static_cast<int32_t>(offline_ids_to_delete.size())); @@ -144,14 +144,13 @@ } if (files_to_delete.size() > 0) { + if (!DeleteFiles(files_to_delete)) + return SyncOperationResult::FILE_OPERATION_ERROR; UMA_HISTOGRAM_COUNTS( "OfflinePages.ConsistencyCheck.Temporary.PagesMissingDbEntryCount", static_cast<int32_t>(files_to_delete.size())); } - if (!DeleteFiles(files_to_delete)) - return SyncOperationResult::FILE_OPERATION_ERROR; - return SyncOperationResult::SUCCESS; }
diff --git a/components/offline_pages/core/offline_page_types.h b/components/offline_pages/core/offline_page_types.h index 609490e..2f4f283b 100644 --- a/components/offline_pages/core/offline_page_types.h +++ b/components/offline_pages/core/offline_page_types.h
@@ -86,6 +86,7 @@ typedef std::vector<int64_t> MultipleOfflineIdResult; typedef std::vector<OfflinePageItem> MultipleOfflinePageItemResult; +// TODO(carlosk): All or most of these should use base::OnceCallback. typedef base::Callback<void(SavePageResult, int64_t)> SavePageCallback; typedef base::Callback<void(AddPageResult, int64_t)> AddPageCallback; typedef base::Callback<void(DeletePageResult)> DeletePageCallback;
diff --git a/components/omnibox/browser/history_url_provider.cc b/components/omnibox/browser/history_url_provider.cc index a28b003e3..03faeea 100644 --- a/components/omnibox/browser/history_url_provider.cc +++ b/components/omnibox/browser/history_url_provider.cc
@@ -403,7 +403,7 @@ const GURL url_with_prefix = url_formatter::FixupURL( base::UTF16ToUTF8(prefix_it->prefix + input.text()), desired_tld); if (url_with_prefix.is_valid() && - db_->GetRowForURL(url_with_prefix, &url_row_)) { + db_->GetRowForURL(url_with_prefix, &url_row_) && !url_row_.hidden()) { type_ = VISITED; return; }
diff --git a/components/omnibox/browser/history_url_provider_unittest.cc b/components/omnibox/browser/history_url_provider_unittest.cc index 5b66e34..aa4a7ce 100644 --- a/components/omnibox/browser/history_url_provider_unittest.cc +++ b/components/omnibox/browser/history_url_provider_unittest.cc
@@ -47,6 +47,7 @@ int visit_count; int typed_count; int age_in_days; + bool hidden = false; } test_db[] = { {"http://www.google.com/", "Google", 3, 3, 80}, @@ -111,6 +112,8 @@ // URLs to test exact-matching behavior. {"http://go/", "Intranet URL", 1, 1, 80}, {"http://gooey/", "Intranet URL 2", 5, 5, 80}, + // This entry is explicitly added as hidden + {"http://g/", "Intranet URL", 7, 7, 80, true}, // URLs for testing offset adjustment. {"http://www.\xEA\xB5\x90\xEC\x9C\xA1.kr/", "Korean", 2, 2, 80}, @@ -124,9 +127,7 @@ // URLs used by EmptyVisits. {"http://pandora.com/", "Pandora", 2, 2, 80}, - // This entry is explicitly added more recently than - // history::kLowQualityMatchAgeLimitInDays. - // {"http://pa/", "pa", 0, 0, 80}, + {"http://pa/", "pa", 0, 0, history::kLowQualityMatchAgeLimitInDays - 1}, // For intranet based tests. {"http://intra/one", "Intranet", 2, 2, 80}, @@ -293,15 +294,9 @@ const GURL current_url(cur.url); client_->GetHistoryService()->AddPageWithDetails( current_url, base::UTF8ToUTF16(cur.title), cur.visit_count, - cur.typed_count, now - TimeDelta::FromDays(cur.age_in_days), false, + cur.typed_count, now - TimeDelta::FromDays(cur.age_in_days), cur.hidden, history::SOURCE_BROWSED); } - - client_->GetHistoryService()->AddPageWithDetails( - GURL("http://pa/"), base::UTF8ToUTF16("pa"), 0, 0, - Time::Now() - - TimeDelta::FromDays(history::kLowQualityMatchAgeLimitInDays - 1), - false, history::SOURCE_BROWSED); } void HistoryURLProviderTest::RunTest( @@ -517,6 +512,8 @@ { "http://gooey/", true }, { "http://www.google.com/", true } }; + // Note that there is an http://g/ URL that is marked as hidden. It shouldn't + // show up at all. This test implicitly tests this fact too. RunTest(ASCIIToUTF16("g"), std::string(), false, short_5a, arraysize(short_5a)); RunTest(ASCIIToUTF16("go"), std::string(), false, short_5b,
diff --git a/components/omnibox/browser/url_index_private_data.cc b/components/omnibox/browser/url_index_private_data.cc index 2bbc03c..49888fa 100644 --- a/components/omnibox/browser/url_index_private_data.cc +++ b/components/omnibox/browser/url_index_private_data.cc
@@ -424,6 +424,7 @@ OmniboxFieldTrial::MaxNumHQPUrlsIndexedAtStartup(); int num_urls_indexed = 0; for (history::URLRow row; history_enum.GetNextURL(&row);) { + DCHECK(RowQualifiesAsSignificant(row, base::Time())); // Do not use >= to account for case of -1 for unlimited urls. if (num_urls_indexed++ == max_urls_indexed) break;
diff --git a/components/password_manager/content/common/OWNERS b/components/password_manager/content/common/OWNERS index 4df0c71..7aebc8abb 100644 --- a/components/password_manager/content/common/OWNERS +++ b/components/password_manager/content/common/OWNERS
@@ -1,4 +1,4 @@ -per-file *_struct_traits*.*=set noparent -per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS +per-file *_mojom_traits*.*=set noparent +per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS per-file *.typemap=set noparent per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/components/password_manager/content/common/credential_manager.typemap b/components/password_manager/content/common/credential_manager.typemap index e77f29f14..6fbe37d 100644 --- a/components/password_manager/content/common/credential_manager.typemap +++ b/components/password_manager/content/common/credential_manager.typemap
@@ -5,9 +5,9 @@ mojom = "//third_party/WebKit/public/platform/modules/credentialmanager/credential_manager.mojom" public_headers = [ "//components/password_manager/core/common/credential_manager_types.h" ] -traits_headers = [ "//components/password_manager/content/common/credential_manager_struct_traits.h" ] +traits_headers = [ "//components/password_manager/content/common/credential_manager_mojom_traits.h" ] sources = [ - "//components/password_manager/content/common/credential_manager_struct_traits.cc", + "//components/password_manager/content/common/credential_manager_mojom_traits.cc", ] deps = [ "//base",
diff --git a/components/password_manager/content/common/credential_manager_struct_traits.cc b/components/password_manager/content/common/credential_manager_mojom_traits.cc similarity index 99% rename from components/password_manager/content/common/credential_manager_struct_traits.cc rename to components/password_manager/content/common/credential_manager_mojom_traits.cc index 3129829..0fb338c 100644 --- a/components/password_manager/content/common/credential_manager_struct_traits.cc +++ b/components/password_manager/content/common/credential_manager_mojom_traits.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/password_manager/content/common/credential_manager_struct_traits.h" +#include "components/password_manager/content/common/credential_manager_mojom_traits.h" #include "url/mojom/origin_mojom_traits.h" #include "url/mojom/url_gurl_mojom_traits.h"
diff --git a/components/password_manager/content/common/credential_manager_struct_traits.h b/components/password_manager/content/common/credential_manager_mojom_traits.h similarity index 97% rename from components/password_manager/content/common/credential_manager_struct_traits.h rename to components/password_manager/content/common/credential_manager_mojom_traits.h index 9f4fec56..23b982e 100644 --- a/components/password_manager/content/common/credential_manager_struct_traits.h +++ b/components/password_manager/content/common/credential_manager_mojom_traits.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_PASSWORD_MANAGER_CONTENT_COMMON_CREDENTIAL_MANAGER_STRUCT_TRAITS_H_ -#define COMPONENTS_PASSWORD_MANAGER_CONTENT_COMMON_CREDENTIAL_MANAGER_STRUCT_TRAITS_H_ +#ifndef COMPONENTS_PASSWORD_MANAGER_CONTENT_COMMON_CREDENTIAL_MANAGER_MOJOM_TRAITS_H_ +#define COMPONENTS_PASSWORD_MANAGER_CONTENT_COMMON_CREDENTIAL_MANAGER_MOJOM_TRAITS_H_ #include "base/strings/string16.h" #include "components/password_manager/core/common/credential_manager_types.h" @@ -76,4 +76,4 @@ } // namespace mojo -#endif // COMPONENTS_PASSWORD_MANAGER_CONTENT_COMMON_CREDENTIAL_MANAGER_STRUCT_TRAITS_H_ +#endif // COMPONENTS_PASSWORD_MANAGER_CONTENT_COMMON_CREDENTIAL_MANAGER_MOJOM_TRAITS_H_
diff --git a/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc b/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc index 0fb0a4d0..d0a2841 100644 --- a/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc +++ b/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc
@@ -118,7 +118,11 @@ bool IsUrlWhitelisted(const GURL& url) override { return false; } bool ShouldSkipRequestCheck(content::ResourceContext* resource_context, - const GURL& original_url) override { + const GURL& original_url, + int frame_tree_node_id, + int render_process_id, + int render_frame_id, + bool originated_from_service_worker) override { return false; }
diff --git a/components/safe_browsing/browser/browser_url_loader_throttle.cc b/components/safe_browsing/browser/browser_url_loader_throttle.cc index 2cce305..1447b38c 100644 --- a/components/safe_browsing/browser/browser_url_loader_throttle.cc +++ b/components/safe_browsing/browser/browser_url_loader_throttle.cc
@@ -8,6 +8,7 @@ #include "base/trace_event/trace_event.h" #include "components/safe_browsing/browser/safe_browsing_url_checker_impl.h" #include "components/safe_browsing/browser/url_checker_delegate.h" +#include "components/safe_browsing/common/safebrowsing_constants.h" #include "components/safe_browsing/common/utils.h" #include "net/log/net_log_event_type.h" #include "net/url_request/redirect_info.h" @@ -141,7 +142,8 @@ url_checker_.reset(); pending_checks_ = 0; pending_slow_checks_ = 0; - delegate_->CancelWithError(net::ERR_ABORTED); + delegate_->CancelWithError(net::ERR_ABORTED, + kCustomCancelReasonForURLLoader); } }
diff --git a/components/safe_browsing/browser/mojo_safe_browsing_impl.cc b/components/safe_browsing/browser/mojo_safe_browsing_impl.cc index b0ec3f6..d8e0b32 100644 --- a/components/safe_browsing/browser/mojo_safe_browsing_impl.cc +++ b/components/safe_browsing/browser/mojo_safe_browsing_impl.cc
@@ -110,9 +110,14 @@ int32_t load_flags, content::ResourceType resource_type, bool has_user_gesture, + bool originated_from_service_worker, CreateCheckerAndCheckCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (delegate_->ShouldSkipRequestCheck(resource_context_, url)) { + + if (delegate_->ShouldSkipRequestCheck(resource_context_, url, + -1 /* frame_tree_node_id */, + render_process_id_, render_frame_id, + originated_from_service_worker)) { // This will drop |request|. The result is that the renderer side will // consider all URLs in the redirect chain of this request as safe. return;
diff --git a/components/safe_browsing/browser/mojo_safe_browsing_impl.h b/components/safe_browsing/browser/mojo_safe_browsing_impl.h index c75bf1fcf..e627f1d 100644 --- a/components/safe_browsing/browser/mojo_safe_browsing_impl.h +++ b/components/safe_browsing/browser/mojo_safe_browsing_impl.h
@@ -48,6 +48,7 @@ int32_t load_flags, content::ResourceType resource_type, bool has_user_gesture, + bool originated_from_service_worker, CreateCheckerAndCheckCallback callback) override; void Clone(mojom::SafeBrowsingRequest request) override;
diff --git a/components/safe_browsing/browser/url_checker_delegate.h b/components/safe_browsing/browser/url_checker_delegate.h index a35155a..5c3dcc0 100644 --- a/components/safe_browsing/browser/url_checker_delegate.h +++ b/components/safe_browsing/browser/url_checker_delegate.h
@@ -56,9 +56,17 @@ // If the method returns true, the entire request won't be checked, including // the original URL and redirects. + // If neither of |render_process_id| and |render_frame_id| is -1, they will be + // used to identify the frame making the request; otherwise + // |frame_tree_node_id| will be used. Please note that |frame_tree_node_id| + // could also be -1, if a request is not associated with a frame. virtual bool ShouldSkipRequestCheck( content::ResourceContext* resource_context, - const GURL& original_url) = 0; + const GURL& original_url, + int frame_tree_node_id, + int render_process_id, + int render_frame_id, + bool originated_from_service_worker) = 0; virtual const SBThreatTypeSet& GetThreatTypes() = 0; virtual SafeBrowsingDatabaseManager* GetDatabaseManager() = 0;
diff --git a/components/safe_browsing/common/safe_browsing.mojom b/components/safe_browsing/common/safe_browsing.mojom index bc447e969..075dcb53 100644 --- a/components/safe_browsing/common/safe_browsing.mojom +++ b/components/safe_browsing/common/safe_browsing.mojom
@@ -45,9 +45,11 @@ network.mojom.HttpRequestHeaders headers, int32 load_flags, content.mojom.ResourceType resource_type, - bool has_user_gesture) => (UrlCheckNotifier&? slow_check_notifier, - bool proceed, - bool showed_interstitial); + bool has_user_gesture, + bool originated_from_service_worker) + => (UrlCheckNotifier&? slow_check_notifier, + bool proceed, + bool showed_interstitial); // Bind an additional pipe to this instance of the SafeBrowsing interface. Clone(SafeBrowsing& request); @@ -62,4 +64,4 @@ interface UrlCheckNotifier { OnCompleteCheck(bool proceed, bool showed_interstitial); -}; \ No newline at end of file +};
diff --git a/components/safe_browsing/common/safebrowsing_constants.cc b/components/safe_browsing/common/safebrowsing_constants.cc index 65c2b54..0281893 100644 --- a/components/safe_browsing/common/safebrowsing_constants.cc +++ b/components/safe_browsing/common/safebrowsing_constants.cc
@@ -32,4 +32,6 @@ const char kSbBackupNetworkErrorURLPrefix[] = "https://alt3-safebrowsing.google.com/safebrowsing"; +const char kCustomCancelReasonForURLLoader[] = "SafeBrowsing"; + } // namespace safe_browsing
diff --git a/components/safe_browsing/common/safebrowsing_constants.h b/components/safe_browsing/common/safebrowsing_constants.h index 598352e3..a339a81d 100644 --- a/components/safe_browsing/common/safebrowsing_constants.h +++ b/components/safe_browsing/common/safebrowsing_constants.h
@@ -29,6 +29,12 @@ // The backup URL prefix used when there are local network specific issues. extern const char kSbBackupNetworkErrorURLPrefix[]; + +// When a network::mojom::URLLoader is cancelled because of SafeBrowsing, this +// custom cancellation reason could be used to notify the implementation side. +// Please see network::mojom::URLLoader::kClientDisconnectReason for more +// details. +extern const char kCustomCancelReasonForURLLoader[]; } #endif // COMPONENTS_SAFE_BROWSING_COMMON_SAFEBROWSING_CONSTANTS_H_
diff --git a/components/safe_browsing/renderer/renderer_url_loader_throttle.cc b/components/safe_browsing/renderer/renderer_url_loader_throttle.cc index c586f25..83d932bb 100644 --- a/components/safe_browsing/renderer/renderer_url_loader_throttle.cc +++ b/components/safe_browsing/renderer/renderer_url_loader_throttle.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/trace_event/trace_event.h" +#include "components/safe_browsing/common/safebrowsing_constants.h" #include "components/safe_browsing/common/utils.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "net/url_request/redirect_info.h" @@ -59,7 +60,7 @@ render_frame_id_, mojo::MakeRequest(&url_checker_), request->url, request->method, headers, request->load_flags, static_cast<content::ResourceType>(request->resource_type), - request->has_user_gesture, + request->has_user_gesture, request->originated_from_service_worker, base::BindOnce(&RendererURLLoaderThrottle::OnCheckUrlResult, weak_factory_.GetWeakPtr())); safe_browsing_ = nullptr; @@ -181,7 +182,8 @@ notifier_bindings_.reset(); pending_checks_ = 0; pending_slow_checks_ = 0; - delegate_->CancelWithError(net::ERR_ABORTED); + delegate_->CancelWithError(net::ERR_ABORTED, + kCustomCancelReasonForURLLoader); } }
diff --git a/components/safe_browsing/renderer/websocket_sb_handshake_throttle.cc b/components/safe_browsing/renderer/websocket_sb_handshake_throttle.cc index 42c39a3..bcc49cba 100644 --- a/components/safe_browsing/renderer/websocket_sb_handshake_throttle.cc +++ b/components/safe_browsing/renderer/websocket_sb_handshake_throttle.cc
@@ -62,7 +62,8 @@ safe_browsing_->CreateCheckerAndCheck( render_frame_id, mojo::MakeRequest(&url_checker_), url, "GET", net::HttpRequestHeaders(), load_flags, - content::RESOURCE_TYPE_SUB_RESOURCE, false, + content::RESOURCE_TYPE_SUB_RESOURCE, false /* has_user_gesture */, + false /* originated_from_service_worker */, base::BindOnce(&WebSocketSBHandshakeThrottle::OnCheckResult, weak_factory_.GetWeakPtr()));
diff --git a/components/safe_browsing/renderer/websocket_sb_handshake_throttle_unittest.cc b/components/safe_browsing/renderer/websocket_sb_handshake_throttle_unittest.cc index 991c1508..7d6dc46 100644 --- a/components/safe_browsing/renderer/websocket_sb_handshake_throttle_unittest.cc +++ b/components/safe_browsing/renderer/websocket_sb_handshake_throttle_unittest.cc
@@ -31,7 +31,8 @@ : render_frame_id_(), load_flags_(-1), resource_type_(), - has_user_gesture_(false) {} + has_user_gesture_(false), + originated_from_service_worker_(false) {} void CreateCheckerAndCheck(int32_t render_frame_id, mojom::SafeBrowsingUrlCheckerRequest request, @@ -41,6 +42,7 @@ int32_t load_flags, content::ResourceType resource_type, bool has_user_gesture, + bool originated_from_service_worker, CreateCheckerAndCheckCallback callback) override { render_frame_id_ = render_frame_id; request_ = std::move(request); @@ -50,6 +52,7 @@ load_flags_ = load_flags; resource_type_ = resource_type; has_user_gesture_ = has_user_gesture; + originated_from_service_worker_ = originated_from_service_worker; callback_ = std::move(callback); run_loop_.Quit(); } @@ -66,6 +69,7 @@ int32_t load_flags_; content::ResourceType resource_type_; bool has_user_gesture_; + bool originated_from_service_worker_; CreateCheckerAndCheckCallback callback_; base::RunLoop run_loop_; }; @@ -127,6 +131,7 @@ EXPECT_EQ(0, safe_browsing_.load_flags_); EXPECT_EQ(content::RESOURCE_TYPE_SUB_RESOURCE, safe_browsing_.resource_type_); EXPECT_FALSE(safe_browsing_.has_user_gesture_); + EXPECT_FALSE(safe_browsing_.originated_from_service_worker_); EXPECT_TRUE(safe_browsing_.callback_); }
diff --git a/components/task_scheduler_util/common/variations_util.cc b/components/task_scheduler_util/common/variations_util.cc index 6ef597a..98bc949 100644 --- a/components/task_scheduler_util/common/variations_util.cc +++ b/components/task_scheduler_util/common/variations_util.cc
@@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/logging.h" +#include "base/metrics/field_trial_params.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -121,6 +122,14 @@ *foreground_worker_pool_params, *foreground_blocking_worker_pool_params); } +std::unique_ptr<base::TaskScheduler::InitParams> GetTaskSchedulerInitParams( + base::StringPiece variation_param_prefix) { + std::map<std::string, std::string> variation_params; + if (!base::GetFieldTrialParams("BrowserScheduler", &variation_params)) + return nullptr; + return GetTaskSchedulerInitParams(variation_param_prefix, variation_params); +} + #if !defined(OS_IOS) void AddVariationParamsToCommandLine(base::StringPiece key_prefix, base::CommandLine* command_line) {
diff --git a/components/task_scheduler_util/common/variations_util.h b/components/task_scheduler_util/common/variations_util.h index d053d2a..9a755e8 100644 --- a/components/task_scheduler_util/common/variations_util.h +++ b/components/task_scheduler_util/common/variations_util.h
@@ -22,10 +22,19 @@ // Builds a TaskScheduler::InitParams from pool descriptors in // |variations_params| that are prefixed with |variation_param_prefix|. Returns // nullptr on failure. +// +// TODO(fdoray): Migrate callers to the overload below and remove this. +// https://crbug.com/810049 std::unique_ptr<base::TaskScheduler::InitParams> GetTaskSchedulerInitParams( base::StringPiece variation_param_prefix, const std::map<std::string, std::string>& variation_params); +// Builds a TaskScheduler::InitParams from variations params that are prefixed +// with |variation_param_prefix| in the BrowserScheduler field trial. Returns +// nullptr on failure. +std::unique_ptr<base::TaskScheduler::InitParams> GetTaskSchedulerInitParams( + base::StringPiece variation_param_prefix); + #if !defined(OS_IOS) // Serializes variation params from the BrowserScheduler field trial whose key // start with |prefix| to the --task-scheduler-variation-params switch of
diff --git a/components/test/data/omnibox/in_memory_url_index_test.sql b/components/test/data/omnibox/in_memory_url_index_test.sql index 93386ab..297069db3 100644 --- a/components/test/data/omnibox/in_memory_url_index_test.sql +++ b/components/test/data/omnibox/in_memory_url_index_test.sql
@@ -55,7 +55,7 @@ INSERT INTO "urls" VALUES(9,'http://en.wikipedia.org/wiki/Control-Z','Control-Z - Wikipedia, the free encyclopedia',0,0,6,0); INSERT INTO "urls" VALUES(10,'http://vmware.com/info?id=724','VMware Account Management Login',1,0,6,0); INSERT INTO "urls" VALUES(11,'http://www.tech-recipes.com/rx/2621/os_x_change_path_environment_variable/','OS X: Change your PATH environment variable | Mac system administration | Tech-Recipes',0,1,6,0); -- Qualifies -INSERT INTO "urls" VALUES(12,'http://view.atdmt.com/PPJ/iview/194841301/direct;wi.160;hi.600/01?click=','',6,6,0,1); -- Qualifies +INSERT INTO "urls" VALUES(12,'http://view.atdmt.com/PPJ/iview/194841301/direct;wi.160;hi.600/01?click=','',6,6,0,0); -- Qualifies INSERT INTO "urls" VALUES(15,'http://www.cnn.com/','CNN.com International - Breaking, World, Business, Sports, Entertainment and Video News',6,6,0,0); -- Qualifies INSERT INTO "urls" VALUES(16,'http://www.zdnet.com/','Technology News, Analysis, Comments and Product Reviews for IT Professionals | ZDNet',6,6,0,0); -- Qualifies INSERT INTO "urls" VALUES(17,'http://www.crash.net/','Crash.Net | Formula 1 & MotoGP | Motorsport News',6,6,0,0); -- Qualifies @@ -70,7 +70,7 @@ INSERT INTO "urls" VALUES(26,'http://www.codeproject.com/','Your Development Resource - CodeProject',6,6,0,0); -- Qualifies INSERT INTO "urls" VALUES(27,'http://www.tomshardware.com/us/#redir','Tom''s Hardware: Hardware News, Tests and Reviews',6,6,0,0); -- Qualifies INSERT INTO "urls" VALUES(28,'http://www.ddj.com/windows/184416623','Dr. ABRACADABRA''s | Avoiding the Visual C++ Runtime Library | 2 1, 2003',6,6,0,0); -- Qualifies -INSERT INTO "urls" VALUES(29,'http://svcs.cnn.com/weather/getForecast?time=34&mode=json_html&zipCode=336736767676&locCode=EGLL&celcius=true&csiID=csi2','',6,6,0,1); -- Qualifies +INSERT INTO "urls" VALUES(29,'http://svcs.cnn.com/weather/getForecast?time=34&mode=json_html&zipCode=336736767676&locCode=EGLL&celcius=true&csiID=csi2','',6,6,0,0); -- Qualifies INSERT INTO "urls" VALUES(30,'http://www.drudgery.com/Dogs%20and%20Mice','Life in the Slow Lane',8,2,2,0); -- Qualifies INSERT INTO "urls" VALUES(31,'http://www.redrudgerydo.com/','Music of the Wild Landscape',0,0,6,0); INSERT INTO "urls" VALUES(32,'https://NearlyPerfectResult.com/','Practically Perfect Search Result',99,99,0,0); -- Qualifies @@ -78,6 +78,8 @@ INSERT INTO "urls" VALUES(34,'http://FubarFubarAndFubar.com/','Situation Normal -- FUBARED',99,99,0,0); -- Qualifies INSERT INTO "urls" VALUES(35,'http://en.wikipedia.org/wiki/1%25_rule_(Internet_culture)','Do Not Need Title',2,2,0,0); -- Qualifies INSERT INTO "urls" VALUES(36,'http://default-engine.com?q=query','Query Query Query',2,2,0,0); -- Qualifies +INSERT INTO "urls" VALUES(37,'http://view.atdmt.com/PPJ/iview/194841301/hidden/direct;wi.160;hi.600/01?click=','',6,6,0,1); +INSERT INTO "urls" VALUES(38,'http://svcs.cnn.com/hidden/weather/getForecast?time=34&mode=json_html&zipCode=336736767676&locCode=EGLL&celcius=true&csiID=csi2','',6,6,0,1); -- This file creates some visits, enough to test (in InMemoryURLIndexTest) -- the visits functionality, certainly not as many visits as are implied
diff --git a/components/url_pattern_index/url_pattern.cc b/components/url_pattern_index/url_pattern.cc index 77c13712..aea83211 100644 --- a/components/url_pattern_index/url_pattern.cc +++ b/components/url_pattern_index/url_pattern.cc
@@ -20,6 +20,7 @@ #include <ostream> #include "base/logging.h" +#include "base/numerics/checked_math.h" #include "components/url_pattern_index/flat/url_pattern_index_generated.h" #include "components/url_pattern_index/fuzzy_pattern_matching.h" #include "components/url_pattern_index/string_splitter.h" @@ -101,13 +102,38 @@ const bool is_fuzzy = (subpattern.find(kSeparatorPlaceholder) != base::StringPiece::npos); - for (size_t position = 0; position <= url.size(); ++position) { - position = is_fuzzy ? FindFuzzy(url, subpattern, position) - : url.find(subpattern, position); + // Any match found after the end of the host will be discarded, so just + // avoid searching there for the subpattern to begin with. + // + // Check for overflow. + size_t max_match_end = 0; + if (!base::CheckAdd(host.end(), subpattern.length()) + .AssignIfValid(&max_match_end)) { + return base::StringPiece::npos; + } + const base::StringPiece url_match_candidate = url.substr(0, max_match_end); + const base::StringPiece url_host = url.substr(0, host.end()); + + for (size_t position = static_cast<size_t>(host.begin); + position <= static_cast<size_t>(host.end()); ++position) { + // Enforce as a loop precondition that we are always anchored at a + // sub-domain before calling find. This is to reduce the number of potential + // searches for |subpattern|. + DCHECK(IsSubdomainAnchored(url, host, position)); + + position = is_fuzzy ? FindFuzzy(url_match_candidate, subpattern, position) + : url_match_candidate.find(subpattern, position); if (position == base::StringPiece::npos || IsSubdomainAnchored(url, host, position)) { return position; } + + // Enforce the loop precondition. This skips |position| to the next '.', + // within the host, which the loop itself increments to the anchored + // sub-domain. + position = url_host.find('.', position); + if (position == base::StringPiece::npos) + break; } return base::StringPiece::npos; }
diff --git a/components/url_pattern_index/url_pattern_unittest.cc b/components/url_pattern_index/url_pattern_unittest.cc index 0943456..3f85fa6 100644 --- a/components/url_pattern_index/url_pattern_unittest.cc +++ b/components/url_pattern_index/url_pattern_unittest.cc
@@ -100,6 +100,7 @@ {{"examp", kSubdomain, kAnchorNone}, "http://test.example.com/", true}, {{"t.examp", kSubdomain, kAnchorNone}, "http://test.example.com/", false}, {{"com^", kSubdomain, kAnchorNone}, "http://test.example.com/", true}, + {{"com^x", kSubdomain, kBoundary}, "http://a.com/x", true}, {{"x.com", kSubdomain, kAnchorNone}, "http://ex.com/?url=x.com", false}, {{"ex.com/", kSubdomain, kBoundary}, "http://ex.com/", true}, {{"ex.com^", kSubdomain, kBoundary}, "http://ex.com/", true}, @@ -110,6 +111,17 @@ {{"http", kSubdomain, kAnchorNone}, "http://http.com/", true}, {{"/example.com", kSubdomain, kBoundary}, "http://example.com/", false}, {{"/example.com/", kSubdomain, kBoundary}, "http://example.com/", false}, + {{".", kSubdomain, kAnchorNone}, "http://a..com/", true}, + {{"^", kSubdomain, kAnchorNone}, "http://a..com/", false}, + {{".", kSubdomain, kAnchorNone}, "http://a.com./", false}, + {{"^", kSubdomain, kAnchorNone}, "http://a.com./", true}, + {{".", kSubdomain, kAnchorNone}, "http://a.com../", true}, + {{"^", kSubdomain, kAnchorNone}, "http://a.com../", true}, + {{"/path", kSubdomain, kAnchorNone}, "http://a.com./path/to/x", true}, + {{"^path", kSubdomain, kAnchorNone}, "http://a.com./path/to/x", true}, + {{"/path", kSubdomain, kBoundary}, "http://a.com./path", true}, + {{"^path", kSubdomain, kBoundary}, "http://a.com./path", true}, + {{"path", kSubdomain, kBoundary}, "http://a.com./path", false}, }; for (const auto& test_case : kTestCases) {
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index b9c31b9..e61922b5 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -5,11 +5,12 @@ #include "components/viz/common/features.h" #include "base/command_line.h" +#include "build/build_config.h" #include "components/viz/common/switches.h" namespace features { -#if defined(USE_AURA) +#if defined(USE_AURA) || defined(OS_MACOSX) const base::Feature kEnableSurfaceSynchronization{ "SurfaceSynchronization", base::FEATURE_ENABLED_BY_DEFAULT}; #else
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc index 6f9d2ff..2b635d3 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -85,6 +85,13 @@ synthetic_begin_frame_source_->SetAuthoritativeVSyncInterval(interval); } +void RootCompositorFrameSinkImpl::SetDisplayVSyncParameters( + base::TimeTicks timebase, + base::TimeDelta interval) { + if (synthetic_begin_frame_source_) + synthetic_begin_frame_source_->OnUpdateVSyncParameters(timebase, interval); +} + void RootCompositorFrameSinkImpl::SetNeedsBeginFrame(bool needs_begin_frame) { support_->SetNeedsBeginFrame(needs_begin_frame); }
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h index b3f49ce..8aae070 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
@@ -51,6 +51,8 @@ const gfx::ColorSpace& device_color_space) override; void SetOutputIsSecure(bool secure) override; void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override; + void SetDisplayVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) override; // mojom::CompositorFrameSink: void SetNeedsBeginFrame(bool needs_begin_frame) override;
diff --git a/content/app/strings/content_strings.grd b/content/app/strings/content_strings.grd index 3dfb3655..47363281 100644 --- a/content/app/strings/content_strings.grd +++ b/content/app/strings/content_strings.grd
@@ -806,11 +806,11 @@ <message name="IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD" desc="Media controls overflow menu item label for a download button."> Download </message> - <message name="IDS_MEDIA_OVERFLOW_MENU_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a picture in picture button."> - Picture in Picture + <message name="IDS_MEDIA_OVERFLOW_MENU_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a picture-in-picture button."> + Picture-in-Picture </message> <message name="IDS_MEDIA_PICTURE_IN_PICTURE_INTERSTITIAL_TEXT" desc="Text message shown to user when in picture in picture mode. When a video is in picture in picture mode, an interstitial with this text appears where the video player is positioned. The video continues to play back in another window that gives the experience that the video is 'popped out'."> - Now in picture in picture mode + Now in Picture-in-Picture mode </message> <message name="IDS_MEDIA_REMOTING_CAST_TEXT" desc="Text message shown to the user when casting a video to a known remote device."> Now casting to <ph name="DEVICE_FRIENDLY_NAME">$1<ex>Living Room TV</ex></ph>
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index a0849d9..47a517a 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -11,7 +11,6 @@ #include "cc/raster/single_thread_task_graph_runner.h" #include "components/viz/client/client_layer_tree_frame_sink.h" #include "components/viz/client/local_surface_id_provider.h" -#include "components/viz/common/features.h" #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/gpu/raster_context_provider.h" #include "components/viz/host/forwarding_compositing_mode_reporter_impl.h" @@ -149,8 +148,6 @@ [](viz::mojom::FrameSinkManagerRequest request, viz::mojom::FrameSinkManagerClientPtrInfo client, viz::mojom::CompositingModeWatcherPtrInfo mode_watcher) { - // TODO(kylechar): Check GpuProcessHost isn't null but don't enter a - // restart loop. GpuProcessHost::Get()->ConnectFrameSinkManager( std::move(request), std::move(client), std::move(mode_watcher)); }; @@ -299,8 +296,10 @@ ui::Compositor* compositor, base::TimeTicks timebase, base::TimeDelta interval) { - // TODO(crbug.com/772524): Deal with vsync later. - NOTIMPLEMENTED(); + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + iter->second.display_private->SetDisplayVSyncParameters(timebase, interval); } void VizProcessTransportFactory::IssueExternalBeginFrame( @@ -406,9 +405,6 @@ } void VizProcessTransportFactory::OnContextLost() { - // TODO(kylechar): If the context is lost but the GPU process hasn't crashed - // then CompositorFrameSink data in HostFrameSinkManager (browser process) and - // FrameSinkManagerImpl (GPU process) needs to be cleaned up. base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&VizProcessTransportFactory::OnLostMainThreadSharedContext, @@ -509,8 +505,7 @@ params.pipes.client_request = std::move(client_request); params.local_surface_id_provider = std::make_unique<viz::DefaultLocalSurfaceIdProvider>(); - params.enable_surface_synchronization = - features::IsSurfaceSynchronizationEnabled(); + params.enable_surface_synchronization = true; scoped_refptr<viz::ContextProvider> compositor_context; scoped_refptr<viz::RasterContextProvider> worker_context;
diff --git a/content/browser/frame_host/form_submission_throttle_browsertest.cc b/content/browser/frame_host/form_submission_throttle_browsertest.cc index 9a70186..2f8454e 100644 --- a/content/browser/frame_host/form_submission_throttle_browsertest.cc +++ b/content/browser/frame_host/form_submission_throttle_browsertest.cc
@@ -77,7 +77,8 @@ false, // started_from_context_menu CSPDisposition::CHECK, // should_check_main_world_csp true, // is_form_submission - base::nullopt); // suggested_filename + base::nullopt, // suggested_filename + nullptr); // navigation_ui_data // Test the expectations with a FormSubmissionThrottle. std::unique_ptr<NavigationThrottle> throttle = @@ -118,7 +119,8 @@ false, // started_from_context_menu CSPDisposition::DO_NOT_CHECK, // should_check_main_world_csp true, // is_form_submission - base::nullopt); // suggested_filename + base::nullopt, // suggested_filename + nullptr); // navigation_ui_data // Test that the navigation is allowed because "should_by_pass_main_world_csp" // is true, even if it is a form submission and the policy is
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index ff1c38d6..1d62c72 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -465,7 +465,7 @@ pending_entry_->SetTransitionType(ui::PAGE_TRANSITION_RELOAD); } - NavigateToPendingEntry(reload_type); + NavigateToPendingEntry(reload_type, nullptr /* navigation_ui_data */); } } @@ -501,14 +501,15 @@ } void NavigationControllerImpl::LoadEntry( - std::unique_ptr<NavigationEntryImpl> entry) { + std::unique_ptr<NavigationEntryImpl> entry, + std::unique_ptr<NavigationUIData> navigation_ui_data) { DiscardPendingEntry(false); // When navigating to a new page, we don't know for sure if we will actually // end up leaving the current page. The new page load could for example // result in a download or a 'no content' response (e.g., a mailto: URL). SetPendingEntry(std::move(entry)); - NavigateToPendingEntry(ReloadType::NONE); + NavigateToPendingEntry(ReloadType::NONE, std::move(navigation_ui_data)); } void NavigationControllerImpl::SetPendingEntry( @@ -679,7 +680,7 @@ pending_entry_index_ = index; pending_entry_->SetTransitionType(ui::PageTransitionFromInt( pending_entry_->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK)); - NavigateToPendingEntry(ReloadType::NONE); + NavigateToPendingEntry(ReloadType::NONE, nullptr /* navigation_ui_data */); } void NavigationControllerImpl::GoToOffset(int offset) { @@ -769,8 +770,11 @@ std::unique_ptr<NavigationEntryImpl> entry; - // For subframes, create a pending entry with a corresponding frame entry. int frame_tree_node_id = params.frame_tree_node_id; + // navigation_ui_data should only be present for main frame navigations. + DCHECK(frame_tree_node_id == -1 || !params.navigation_ui_data); + + // For subframes, create a pending entry with a corresponding frame entry. if (frame_tree_node_id != -1 || !params.frame_name.empty()) { FrameTreeNode* node = params.frame_tree_node_id != -1 @@ -857,8 +861,14 @@ break; } + // TODO(clamy): NavigationEntry is meant for information that will be kept + // after the navigation ended and therefore is not appropriate for + // started_from_context_menu. Move started_from_context_menu to + // NavigationUIData. entry->set_started_from_context_menu(params.started_from_context_menu); - LoadEntry(std::move(entry)); + LoadEntry(std::move(entry), params.navigation_ui_data + ? params.navigation_ui_data->Clone() + : nullptr); } bool NavigationControllerImpl::PendingEntryMatchesHandle( @@ -1997,7 +2007,9 @@ } } -void NavigationControllerImpl::NavigateToPendingEntry(ReloadType reload_type) { +void NavigationControllerImpl::NavigateToPendingEntry( + ReloadType reload_type, + std::unique_ptr<NavigationUIData> navigation_ui_data) { DCHECK(pending_entry_); needs_reload_ = false; @@ -2068,7 +2080,8 @@ // This call does not support re-entrancy. See http://crbug.com/347742. CHECK(!in_navigate_to_pending_entry_); in_navigate_to_pending_entry_ = true; - bool success = NavigateToPendingEntryInternal(reload_type); + bool success = NavigateToPendingEntryInternal(reload_type, + std::move(navigation_ui_data)); in_navigate_to_pending_entry_ = false; if (!success) @@ -2076,7 +2089,8 @@ } bool NavigationControllerImpl::NavigateToPendingEntryInternal( - ReloadType reload_type) { + ReloadType reload_type, + std::unique_ptr<NavigationUIData> navigation_ui_data) { DCHECK(pending_entry_); FrameTreeNode* root = delegate_->GetFrameTree()->root(); @@ -2106,13 +2120,17 @@ // Send all the same document frame loads before the different document loads. for (const auto& item : same_document_loads) { FrameTreeNode* frame = item.first; - success |= frame->navigator()->NavigateToPendingEntry(frame, *item.second, - reload_type, true); + success |= frame->navigator()->NavigateToPendingEntry( + frame, *item.second, reload_type, true, + nullptr /* navigation_ui_data */); } for (const auto& item : different_document_loads) { FrameTreeNode* frame = item.first; - success |= frame->navigator()->NavigateToPendingEntry(frame, *item.second, - reload_type, false); + success |= frame->navigator()->NavigateToPendingEntry( + frame, *item.second, reload_type, false, + // The NavigationUIData has only been initialized for main frames. Do + // not pass it to subframes. + frame->IsMainFrame() ? std::move(navigation_ui_data) : nullptr); } return success; } @@ -2219,11 +2237,11 @@ // Explicitly use NavigateToPendingEntry so that the renderer uses the // cached state. if (pending_entry_) { - NavigateToPendingEntry(ReloadType::NONE); + NavigateToPendingEntry(ReloadType::NONE, nullptr /* navigation_ui_data */); } else if (last_committed_entry_index_ != -1) { pending_entry_ = entries_[last_committed_entry_index_].get(); pending_entry_index_ = last_committed_entry_index_; - NavigateToPendingEntry(ReloadType::NONE); + NavigateToPendingEntry(ReloadType::NONE, nullptr /* navigation_ui_data */); } else { // If there is something to reload, the successful reload will clear the // |needs_reload_| flag. Otherwise, just do it here.
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h index 202b0fd..3071ec9 100644 --- a/content/browser/frame_host/navigation_controller_impl.h +++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -236,12 +236,15 @@ // Causes the controller to load the specified entry. The function assumes // ownership of the pointer since it is put in the navigation list. // NOTE: Do not pass an entry that the controller already owns! - void LoadEntry(std::unique_ptr<NavigationEntryImpl> entry); + void LoadEntry(std::unique_ptr<NavigationEntryImpl> entry, + std::unique_ptr<NavigationUIData> navigation_ui_data); // Identifies which frames need to be navigated for the pending // NavigationEntry and instructs their Navigator to navigate them. Returns // whether any frame successfully started a navigation. - bool NavigateToPendingEntryInternal(ReloadType reload_type); + bool NavigateToPendingEntryInternal( + ReloadType reload_type, + std::unique_ptr<NavigationUIData> navigation_ui_data); // Recursively identifies which frames need to be navigated for the pending // NavigationEntry, starting at |frame| and exploring its children. Only used @@ -299,7 +302,9 @@ const FrameHostMsg_DidCommitProvisionalLoad_Params& params); // Actually issues the navigation held in pending_entry. - void NavigateToPendingEntry(ReloadType reload_type); + void NavigateToPendingEntry( + ReloadType reload_type, + std::unique_ptr<NavigationUIData> navigation_ui_data); // Allows the derived class to issue notifications that a load has been // committed. This will fill in the active entry to the details structure.
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index ce3db368..d4be972b 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -19,6 +19,7 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/gtest_util.h" #include "base/time/time.h" #include "build/build_config.h" #include "content/browser/frame_host/frame_navigation_entry.h" @@ -44,6 +45,7 @@ #include "content/public/test/browser_side_navigation_test_utils.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/navigation_simulator.h" +#include "content/public/test/test_navigation_ui_data.h" #include "content/public/test/test_utils.h" #include "content/test/test_render_frame_host.h" #include "content/test/test_render_view_host.h" @@ -309,6 +311,7 @@ bool is_same_document() { return is_same_document_; } bool is_main_frame() { return is_main_frame_; } bool did_replace_entry() { return did_replace_entry_; } + bool has_navigation_ui_data() { return has_navigation_ui_data_; } private: void DidFinishNavigation(NavigationHandle* navigation_handle) override { @@ -321,6 +324,7 @@ is_same_document_ = navigation_handle->IsSameDocument(); is_main_frame_ = navigation_handle->IsInMainFrame(); did_replace_entry_ = navigation_handle->DidReplaceEntry(); + has_navigation_ui_data_ = navigation_handle->GetNavigationUIData(); } NavigationType navigation_type_; @@ -328,6 +332,7 @@ bool is_same_document_; bool is_main_frame_; bool did_replace_entry_; + bool has_navigation_ui_data_; }; // PlzNavigate @@ -5329,4 +5334,55 @@ EXPECT_EQ(url_1, controller.GetEntryAtIndex(1)->GetURL()); } +// Tests that NavigationUIData has been passed to the NavigationHandle. +TEST_F(NavigationControllerTest, MainFrameNavigationUIData) { + NavigationControllerImpl& controller = controller_impl(); + LoadCommittedDetailsObserver observer(contents()); + const GURL url1("http://foo1"); + + NavigationController::LoadURLParams params(url1); + params.navigation_ui_data = std::make_unique<TestNavigationUIData>(); + controller.LoadURLWithParams(params); + int entry_id = controller.GetPendingEntry()->GetUniqueID(); + + main_test_rfh()->PrepareForCommit(); + main_test_rfh()->SendNavigate(entry_id, true, url1); + + EXPECT_TRUE(observer.is_main_frame()); + EXPECT_TRUE(observer.has_navigation_ui_data()); +} + +// Tests calling LoadURLParams with NavigationUIData and for a sub frame. +TEST_F(NavigationControllerTest, SubFrameNavigationUIData) { + // Navigate to a page. + const GURL url1("http://foo1"); + NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh()); + EXPECT_EQ(1U, navigation_entry_committed_counter_); + navigation_entry_committed_counter_ = 0; + + // Add a sub frame. + std::string unique_name("uniqueName0"); + main_test_rfh()->OnCreateChildFrame( + process()->GetNextRoutingID(), + TestRenderFrameHost::CreateStubInterfaceProviderRequest(), + blink::WebTreeScopeType::kDocument, std::string(), unique_name, false, + base::UnguessableToken::Create(), blink::FramePolicy(), + FrameOwnerProperties()); + TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>( + contents()->GetFrameTree()->root()->child_at(0)->current_frame_host()); + const GURL subframe_url("http://foo1/subframe"); + + LoadCommittedDetailsObserver observer(contents()); + + // Navigate sub frame. + NavigationController::LoadURLParams params(url1); + params.navigation_ui_data = std::make_unique<TestNavigationUIData>(); + params.frame_tree_node_id = subframe->GetFrameTreeNodeId(); + +#if DCHECK_IS_ON() + // We DCHECK to prevent misuse of the API. + EXPECT_DEATH_IF_SUPPORTED(controller_impl().LoadURLWithParams(params), ""); +#endif +} + } // namespace content
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 913f1d9e..355fd89c 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -72,6 +72,7 @@ CSPDisposition should_check_main_world_csp, bool is_form_submission, const base::Optional<std::string>& suggested_filename, + std::unique_ptr<NavigationUIData> navigation_ui_data, const std::string& method, scoped_refptr<network::ResourceRequestBody> resource_request_body, const Referrer& sanitized_referrer, @@ -84,9 +85,10 @@ url, redirect_chain, frame_tree_node, is_renderer_initiated, is_same_document, navigation_start, pending_nav_entry_id, started_from_context_menu, should_check_main_world_csp, - is_form_submission, suggested_filename, method, resource_request_body, - sanitized_referrer, has_user_gesture, transition, is_external_protocol, - request_context_type, mixed_content_context_type)); + is_form_submission, suggested_filename, std::move(navigation_ui_data), + method, resource_request_body, sanitized_referrer, has_user_gesture, + transition, is_external_protocol, request_context_type, + mixed_content_context_type)); } NavigationHandleImpl::NavigationHandleImpl( @@ -101,6 +103,7 @@ CSPDisposition should_check_main_world_csp, bool is_form_submission, const base::Optional<std::string>& suggested_filename, + std::unique_ptr<NavigationUIData> navigation_ui_data, const std::string& method, scoped_refptr<network::ResourceRequestBody> resource_request_body, const Referrer& sanitized_referrer, @@ -132,6 +135,7 @@ pending_nav_entry_id_(pending_nav_entry_id), request_context_type_(request_context_type), mixed_content_context_type_(mixed_content_context_type), + navigation_ui_data_(std::move(navigation_ui_data)), navigation_id_(CreateUniqueHandleID()), should_replace_current_entry_(false), redirect_chain_(redirect_chain), @@ -315,6 +319,10 @@ return transition_; } +const NavigationUIData* NavigationHandleImpl::GetNavigationUIData() { + return navigation_ui_data_.get(); +} + bool NavigationHandleImpl::IsExternalProtocol() { return is_external_protocol_; } @@ -565,7 +573,10 @@ RegisterNavigationThrottles(); - navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this); + // If the content/ embedder did not pass the NavigationUIData at the beginning + // of the navigation, ask for it now. + if (!navigation_ui_data_) + navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this); // Notify each throttle of the request. base::Closure on_defer_callback_copy = on_defer_callback_for_testing_;
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index 5e2b7ba..576bca7 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -67,6 +67,7 @@ CSPDisposition should_check_main_world_csp, bool is_form_submission, const base::Optional<std::string>& suggested_filename, + std::unique_ptr<NavigationUIData> navigation_ui_data, const std::string& method = std::string(), scoped_refptr<network::ResourceRequestBody> resource_request_body = nullptr, @@ -116,6 +117,7 @@ const Referrer& GetReferrer() override; bool HasUserGesture() override; ui::PageTransition GetPageTransition() override; + const NavigationUIData* GetNavigationUIData() override; bool IsExternalProtocol() override; net::Error GetNetErrorCode() override; RenderFrameHostImpl* GetRenderFrameHost() override; @@ -378,6 +380,7 @@ CSPDisposition should_check_main_world_csp, bool is_form_submission, const base::Optional<std::string>& suggested_filename, + std::unique_ptr<NavigationUIData> navigation_ui_data, const std::string& method, scoped_refptr<network::ResourceRequestBody> resource_request_body, const Referrer& sanitized_referrer,
diff --git a/content/browser/frame_host/navigation_handle_impl_unittest.cc b/content/browser/frame_host/navigation_handle_impl_unittest.cc index 7fce862..f78ce7c 100644 --- a/content/browser/frame_host/navigation_handle_impl_unittest.cc +++ b/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -259,6 +259,7 @@ CSPDisposition::CHECK, // should_check_main_world_csp false, // is_form_submission base::nullopt, // suggested_filename + nullptr, // navigation_ui_data "GET", nullptr, // resource_request_body Referrer(),
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 374e248..54f685d 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -239,7 +239,8 @@ bool is_history_navigation_in_new_child, const scoped_refptr<network::ResourceRequestBody>& post_body, const base::TimeTicks& navigation_start, - NavigationControllerImpl* controller) { + NavigationControllerImpl* controller, + std::unique_ptr<NavigationUIData> navigation_ui_data) { // A form submission happens either because the navigation is a // renderer-initiated form submission that took the OpenURL path or a // back/forward/reload navigation the does a form resubmission. @@ -295,7 +296,7 @@ std::string() /* searchable_form_encoding */, initiator, GURL() /* client_side_redirect_url */), request_params, browser_initiated, false /* from_begin_navigation */, - &frame_entry, &entry)); + &frame_entry, &entry, std::move(navigation_ui_data))); return navigation_request; } @@ -340,7 +341,8 @@ frame_tree_node, common_params, std::move(begin_params), request_params, false, // browser_initiated true, // from_begin_navigation - nullptr, entry)); + nullptr, entry, + nullptr)); // navigation_ui_data return navigation_request; } @@ -352,12 +354,14 @@ bool browser_initiated, bool from_begin_navigation, const FrameNavigationEntry* frame_entry, - const NavigationEntryImpl* entry) + const NavigationEntryImpl* entry, + std::unique_ptr<NavigationUIData> navigation_ui_data) : frame_tree_node_(frame_tree_node), common_params_(common_params), begin_params_(std::move(begin_params)), request_params_(request_params), browser_initiated_(browser_initiated), + navigation_ui_data_(std::move(navigation_ui_data)), state_(NOT_STARTED), restore_type_(RestoreType::NONE), is_view_source_(false), @@ -572,7 +576,8 @@ common_params_.started_from_context_menu, common_params_.should_check_main_world_csp, begin_params_->is_form_submission, common_params_.suggested_filename, - common_params_.method, common_params_.post_data, + std::move(navigation_ui_data_), common_params_.method, + common_params_.post_data, Referrer::SanitizeForRequest(common_params_.url, common_params_.referrer), common_params_.has_user_gesture, common_params_.transition, @@ -1146,8 +1151,8 @@ : frame_tree_node_->parent()->IsMainFrame(); std::unique_ptr<NavigationUIData> navigation_ui_data; - if (navigation_handle_->navigation_ui_data()) - navigation_ui_data = navigation_handle_->navigation_ui_data()->Clone(); + if (navigation_handle_->GetNavigationUIData()) + navigation_ui_data = navigation_handle_->GetNavigationUIData()->Clone(); bool is_for_guests_only = navigation_handle_->GetStartingSiteInstance()->GetSiteURL().
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 32789d3..19dd784 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -34,6 +34,7 @@ class NavigationHandleImpl; class NavigationURLLoader; class NavigationData; +class NavigationUIData; class SiteInstanceImpl; class StreamHandle; struct SubresourceLoaderParams; @@ -91,7 +92,8 @@ bool is_history_navigation_in_new_child, const scoped_refptr<network::ResourceRequestBody>& post_body, const base::TimeTicks& navigation_start, - NavigationControllerImpl* controller); + NavigationControllerImpl* controller, + std::unique_ptr<NavigationUIData> navigation_ui_data); // Creates a request for a renderer-intiated navigation. // Note: |body| is sent to the IO thread when calling BeginNavigation, and @@ -218,7 +220,8 @@ bool browser_initiated, bool from_begin_navigation, const FrameNavigationEntry* frame_navigation_entry, - const NavigationEntryImpl* navitation_entry); + const NavigationEntryImpl* navitation_entry, + std::unique_ptr<NavigationUIData> navigation_ui_data); // NavigationURLLoaderDelegate implementation. void OnRequestRedirected( @@ -320,6 +323,11 @@ RequestNavigationParams request_params_; const bool browser_initiated_; + // Stores the NavigationUIData for this navigation until the NavigationHandle + // is created. This can be null if the embedded did not provide a + // NavigationUIData at the beginning of the navigation. + std::unique_ptr<NavigationUIData> navigation_ui_data_; + NavigationState state_; std::unique_ptr<NavigationURLLoader> loader_;
diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc index 3274e061..a945fbc 100644 --- a/content/browser/frame_host/navigator.cc +++ b/content/browser/frame_host/navigator.cc
@@ -17,10 +17,12 @@ return nullptr; } -bool Navigator::NavigateToPendingEntry(FrameTreeNode* frame_tree_node, - const FrameNavigationEntry& frame_entry, - ReloadType reload_type, - bool is_same_document_history_load) { +bool Navigator::NavigateToPendingEntry( + FrameTreeNode* frame_tree_node, + const FrameNavigationEntry& frame_entry, + ReloadType reload_type, + bool is_same_document_history_load, + std::unique_ptr<NavigationUIData> navigation_ui_data) { return false; }
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h index b4bed47..771a0b9 100644 --- a/content/browser/frame_host/navigator.h +++ b/content/browser/frame_host/navigator.h
@@ -95,10 +95,12 @@ // TODO(nasko): Remove this method from the interface, since Navigator and // NavigationController know about each other. This will be possible once // initialization of Navigator and NavigationController is properly done. - virtual bool NavigateToPendingEntry(FrameTreeNode* frame_tree_node, - const FrameNavigationEntry& frame_entry, - ReloadType reload_type, - bool is_same_document_history_load); + virtual bool NavigateToPendingEntry( + FrameTreeNode* frame_tree_node, + const FrameNavigationEntry& frame_entry, + ReloadType reload_type, + bool is_same_document_history_load, + std::unique_ptr<NavigationUIData> navigation_ui_data); // Called on a newly created subframe during a history navigation. The browser // process looks up the corresponding FrameNavigationEntry for the new frame
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 793f1ab2..5a2bddf 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -263,7 +263,8 @@ bool is_same_document_history_load, bool is_history_navigation_in_new_child, bool is_pending_entry, - const scoped_refptr<network::ResourceRequestBody>& post_body) { + const scoped_refptr<network::ResourceRequestBody>& post_body, + std::unique_ptr<NavigationUIData> navigation_ui_data) { TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); GURL dest_url = frame_entry.url(); @@ -334,10 +335,11 @@ navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url, entry.restore_type())); - RequestNavigation( - frame_tree_node, dest_url, dest_referrer, frame_entry, entry, reload_type, - previews_state, is_same_document_history_load, - is_history_navigation_in_new_child, post_body, navigation_start); + RequestNavigation(frame_tree_node, dest_url, dest_referrer, frame_entry, + entry, reload_type, previews_state, + is_same_document_history_load, + is_history_navigation_in_new_child, post_body, + navigation_start, std::move(navigation_ui_data)); if (frame_tree_node->IsMainFrame() && frame_tree_node->navigation_request()) { // For the trace below we're using the navigation handle as the async // trace id, |navigation_start| as the timestamp and reporting the @@ -380,10 +382,12 @@ FrameTreeNode* frame_tree_node, const FrameNavigationEntry& frame_entry, ReloadType reload_type, - bool is_same_document_history_load) { + bool is_same_document_history_load, + std::unique_ptr<NavigationUIData> navigation_ui_data) { return NavigateToEntry(frame_tree_node, frame_entry, *controller_->GetPendingEntry(), reload_type, - is_same_document_history_load, false, true, nullptr); + is_same_document_history_load, false, true, nullptr, + std::move(navigation_ui_data)); } bool NavigatorImpl::NavigateNewChildFrame( @@ -420,7 +424,8 @@ } return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, - *entry, ReloadType::NONE, false, true, false, nullptr); + *entry, ReloadType::NONE, false, true, false, nullptr, + nullptr /* navigation_ui_data */); } void NavigatorImpl::DidNavigate( @@ -788,7 +793,7 @@ referrer_to_use, redirect_chain, PageState(), method, -1); } NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false, - false, false, post_body); + false, false, post_body, nullptr /* navigation_ui_data */); } void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, @@ -1022,7 +1027,8 @@ bool is_same_document_history_load, bool is_history_navigation_in_new_child, const scoped_refptr<network::ResourceRequestBody>& post_body, - base::TimeTicks navigation_start) { + base::TimeTicks navigation_start, + std::unique_ptr<NavigationUIData> navigation_ui_data) { DCHECK(frame_tree_node); // This is not a real navigation. Send the URL to the renderer process @@ -1060,7 +1066,7 @@ frame_tree_node, dest_url, dest_referrer, frame_entry, entry, navigation_type, previews_state, is_same_document_history_load, is_history_navigation_in_new_child, post_body, navigation_start, - controller_); + controller_, std::move(navigation_ui_data)); frame_tree_node->CreatedNavigationRequest(std::move(scoped_request));
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h index e7378b8d..a1bedd3 100644 --- a/content/browser/frame_host/navigator_impl.h +++ b/content/browser/frame_host/navigator_impl.h
@@ -57,10 +57,12 @@ const FrameHostMsg_DidCommitProvisionalLoad_Params& params, std::unique_ptr<NavigationHandleImpl> navigation_handle, bool was_within_same_document) override; - bool NavigateToPendingEntry(FrameTreeNode* frame_tree_node, - const FrameNavigationEntry& frame_entry, - ReloadType reload_type, - bool is_same_document_history_load) override; + bool NavigateToPendingEntry( + FrameTreeNode* frame_tree_node, + const FrameNavigationEntry& frame_entry, + ReloadType reload_type, + bool is_same_document_history_load, + std::unique_ptr<NavigationUIData> navigation_ui_data) override; bool NavigateNewChildFrame(RenderFrameHostImpl* render_frame_host, const GURL& default_url) override; void RequestOpenURL( @@ -124,7 +126,8 @@ bool is_same_document_history_load, bool is_history_navigation_in_new_child, bool is_pending_entry, - const scoped_refptr<network::ResourceRequestBody>& post_body); + const scoped_refptr<network::ResourceRequestBody>& post_body, + std::unique_ptr<NavigationUIData> navigation_ui_data); // If needed, sends a BeforeUnload IPC to the renderer to ask it to execute // the beforeUnload event. Otherwise, the navigation request will be started. @@ -139,7 +142,8 @@ bool is_same_document_history_load, bool is_history_navigation_in_new_child, const scoped_refptr<network::ResourceRequestBody>& post_body, - base::TimeTicks navigation_start); + base::TimeTicks navigation_start, + std::unique_ptr<NavigationUIData> navigation_ui_data); void RecordNavigationMetrics( const LoadCommittedDetails& details,
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 96a3e02..5b72b1d 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4425,7 +4425,8 @@ false, // started_from_context_menu CSPDisposition::CHECK, // should_check_main_world_csp false, // is_form_submission - base::nullopt); // suggested_filename + base::nullopt, // suggested_filename + nullptr); // navigation_ui_data } std::unique_ptr<NavigationHandleImpl> @@ -4485,7 +4486,8 @@ false, // started_from_context_menu CSPDisposition::CHECK, // should_check_main_world_csp false, // is_form_submission - base::nullopt); // suggested_filename + base::nullopt, // suggested_filename + nullptr); // navigation_ui_data } void RenderFrameHostImpl::BeforeUnloadTimeout() {
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index a8784cb..edd94f2 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -454,7 +454,7 @@ manager->frame_tree_node_, frame_entry->url(), frame_entry->referrer(), *frame_entry, entry, navigate_type, PREVIEWS_UNSPECIFIED, false, false, nullptr, base::TimeTicks::Now(), - controller); + controller, nullptr); // Simulates request creation that triggers the 1st internal call to // GetFrameHostForNavigation. @@ -2775,7 +2775,7 @@ frame_entry->referrer(), *frame_entry, entry, FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, PREVIEWS_UNSPECIFIED, false, false, nullptr, base::TimeTicks::Now(), - static_cast<NavigationControllerImpl*>(&controller())); + static_cast<NavigationControllerImpl*>(&controller()), nullptr); manager->DidCreateNavigationRequest(navigation_request.get()); // As the initial RenderFrame was not live, the new RenderFrameHost should be @@ -2836,7 +2836,7 @@ frame_entry->referrer(), *frame_entry, entry, FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, PREVIEWS_UNSPECIFIED, false, false, nullptr, base::TimeTicks::Now(), - static_cast<NavigationControllerImpl*>(&controller())); + static_cast<NavigationControllerImpl*>(&controller()), nullptr); manager->DidCreateNavigationRequest(navigation_request.get()); // The current WebUI should still be in place and the pending WebUI should be @@ -2894,7 +2894,7 @@ frame_entry->referrer(), *frame_entry, entry, FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, PREVIEWS_UNSPECIFIED, false, false, nullptr, base::TimeTicks::Now(), - static_cast<NavigationControllerImpl*>(&controller())); + static_cast<NavigationControllerImpl*>(&controller()), nullptr); manager->DidCreateNavigationRequest(navigation_request.get()); // The current WebUI should still be in place and there should be a new
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index 92d3ee3..cbd9117 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -344,13 +344,14 @@ DCHECK(!started_); started_ = true; + frame_tree_node_id_ = request_info->frame_tree_node_id; web_contents_getter_ = base::BindRepeating( - &GetWebContentsFromFrameTreeNodeID, request_info->frame_tree_node_id); + &GetWebContentsFromFrameTreeNodeID, frame_tree_node_id_); std::vector<std::unique_ptr<content::URLLoaderThrottle>> throttles = GetContentClient()->browser()->CreateURLLoaderThrottles( *resource_request_, resource_context_, web_contents_getter_, - navigation_ui_data.get()); + navigation_ui_data.get(), frame_tree_node_id_); auto load_single_request = base::BindOnce( &URLLoaderRequestController::CreateNonNetworkServiceURLLoader, @@ -404,7 +405,7 @@ std::move(factory_for_webui)), GetContentClient()->browser()->CreateURLLoaderThrottles( *resource_request_, resource_context_, web_contents_getter_, - navigation_ui_data_.get()), + navigation_ui_data_.get(), frame_tree_node_id_), 0 /* routing_id */, 0 /* request_id? */, network::mojom::kURLLoadOptionNone, resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation, @@ -480,7 +481,7 @@ std::move(single_request_handler)), GetContentClient()->browser()->CreateURLLoaderThrottles( *resource_request_, resource_context_, web_contents_getter_, - navigation_ui_data_.get()), + navigation_ui_data_.get(), frame_tree_node_id_), frame_tree_node_id_, 0 /* request_id? */, network::mojom::kURLLoadOptionNone, resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation, @@ -557,7 +558,7 @@ base::MakeRefCounted<WeakWrapperSharedURLLoaderFactory>(factory), GetContentClient()->browser()->CreateURLLoaderThrottles( *resource_request_, resource_context_, web_contents_getter_, - navigation_ui_data_.get()), + navigation_ui_data_.get(), frame_tree_node_id_), frame_tree_node_id_, 0 /* request_id? */, options, resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation, base::ThreadTaskRunnerHandle::Get());
diff --git a/content/browser/service_worker/service_worker_database.cc b/content/browser/service_worker/service_worker_database.cc index a4efae3f..df8f306d 100644 --- a/content/browser/service_worker/service_worker_database.cc +++ b/content/browser/service_worker/service_worker_database.cc
@@ -1262,6 +1262,9 @@ } else { options.env = g_service_worker_env.Pointer(); } + // The data size is usually small, but the values are changed frequently. So, + // set a low write buffer size to trigger compaction more often. + options.write_buffer_size = 512 * 1024; Status status = LevelDBStatusToServiceWorkerDBStatus( leveldb_env::OpenDB(options, path_.AsUTF8Unsafe(), &db_));
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index d961143..6dcae69 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc
@@ -357,6 +357,12 @@ if (dest_url == blank_page) return true; + // If the source and destination URLs are equal excluding the hash, they have + // the same site. This matters for file URLs, where SameDomainOrHost() would + // otherwise return false below. + if (src_url.EqualsIgnoringRef(dest_url)) + return true; + url::Origin src_origin = url::Origin::Create(src_url); url::Origin dest_origin = url::Origin::Create(dest_url);
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc index 774bf72..ef9538546 100644 --- a/content/browser/site_instance_impl_unittest.cc +++ b/content/browser/site_instance_impl_unittest.cc
@@ -425,6 +425,32 @@ DrainMessageLoop(); } +// Test that two file URLs are considered same-site if they have the same path, +// even if they have different fragments. +TEST_F(SiteInstanceTest, IsSameWebSiteForFileURLs) { + // Two identical file URLs should be same-site. + EXPECT_TRUE(SiteInstance::IsSameWebSite(nullptr, GURL("file:///foo/bar.html"), + GURL("file:///foo/bar.html"))); + + // File URLs with the same path but different fragment are considered + // same-site. + EXPECT_TRUE(SiteInstance::IsSameWebSite(nullptr, GURL("file:///foo/bar.html"), + GURL("file:///foo/bar.html#baz"))); + EXPECT_TRUE(SiteInstance::IsSameWebSite( + nullptr, GURL("file:///foo/bar.html#baz"), GURL("file:///foo/bar.html"))); + EXPECT_TRUE(SiteInstance::IsSameWebSite(nullptr, + GURL("file:///foo/bar.html#baz"), + GURL("file:///foo/bar.html#qux"))); + EXPECT_TRUE(SiteInstance::IsSameWebSite(nullptr, GURL("file:///#abc"), + GURL("file:///#def"))); + + // Other cases are cross-site. + EXPECT_FALSE(SiteInstance::IsSameWebSite(nullptr, GURL("file:///foo.html"), + GURL("file:///foo/bar.html"))); + EXPECT_FALSE(SiteInstance::IsSameWebSite(nullptr, GURL("file:///#bar"), + GURL("file:///foo/#bar"))); +} + // Test to ensure that there is only one SiteInstance per site in a given // BrowsingInstance, when process-per-site is not in use. TEST_F(SiteInstanceTest, OneSiteInstancePerSite) {
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 3596ae22..2d82c0d 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -1080,6 +1080,8 @@ void WebContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { SizeChangedCommon(new_bounds.size()); + if (delegate_) + delegate_->SizeChanged(new_bounds.size()); // Constrained web dialogs, need to be kept centered over our content area. for (size_t i = 0; i < window_->children().size(); i++) {
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index 97016f03..2c5dd9e9 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -708,6 +708,9 @@ - (void)setFrameSize:(NSSize)newSize { [super setFrameSize:newSize]; + if (webContentsView_ && webContentsView_->delegate()) + webContentsView_->delegate()->SizeChanged(gfx::Size(newSize)); + // Perform manual layout of subviews, e.g., when the window size changes. for (NSView* subview in [self subviews]) [subview setFrame:[self bounds]];
diff --git a/content/browser/webrtc/webrtc_event_log_manager.cc b/content/browser/webrtc/webrtc_event_log_manager.cc index 91cf5f88..94837cd4 100644 --- a/content/browser/webrtc/webrtc_event_log_manager.cc +++ b/content/browser/webrtc/webrtc_event_log_manager.cc
@@ -114,7 +114,7 @@ base::OnceClosure reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); CHECK(!browser_context->IsOffTheRecord()); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::EnableForBrowserContextInternal, @@ -127,7 +127,7 @@ BrowserContextId browser_context_id, base::OnceClosure reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::DisableForBrowserContextInternal, @@ -150,7 +150,7 @@ observed_render_process_hosts_.insert(host); } - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::PeerConnectionAddedInternal, @@ -178,7 +178,7 @@ } const BrowserContext* browser_context = host->GetBrowserContext(); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::PeerConnectionRemovedInternal, @@ -199,7 +199,7 @@ base::OnceCallback<void(bool)> reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(!base_path.empty()); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::EnableLocalLoggingInternal, @@ -210,7 +210,7 @@ void WebRtcEventLogManager::DisableLocalLogging( base::OnceCallback<void(bool)> reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::DisableLocalLoggingInternal, @@ -221,6 +221,7 @@ int render_process_id, int lid, size_t max_file_size_bytes, + const std::string& metadata, base::OnceCallback<void(bool)> reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -230,13 +231,13 @@ browser_context_id = GetBrowserContextId(browser_context); } - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::StartRemoteLoggingInternal, base::Unretained(this), render_process_id, lid, browser_context_id, browser_context->GetPath(), - max_file_size_bytes, std::move(reply))); + max_file_size_bytes, metadata, std::move(reply))); } void WebRtcEventLogManager::OnWebRtcEventLogWrite( @@ -246,7 +247,7 @@ base::OnceCallback<void(std::pair<bool, bool>)> reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); const BrowserContext* browser_context = GetBrowserContext(render_process_id); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::OnWebRtcEventLogWriteInternal, @@ -259,7 +260,7 @@ WebRtcLocalEventLogsObserver* observer, base::OnceClosure reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::SetLocalLogsObserverInternal, @@ -270,7 +271,7 @@ WebRtcRemoteEventLogsObserver* observer, base::OnceClosure reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::SetRemoteLogsObserverInternal, @@ -308,7 +309,7 @@ host->RemoveObserver(this); observed_render_process_hosts_.erase(host); - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcEventLogManager::RenderProcessExitedInternal, @@ -473,6 +474,7 @@ base::Optional<BrowserContextId> browser_context_id, const base::FilePath& browser_context_dir, size_t max_file_size_bytes, + const std::string metadata, base::OnceCallback<void(bool)> reply) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); @@ -480,7 +482,7 @@ if (browser_context_id) { // Not off the records. result = remote_logs_manager_.StartRemoteLogging( render_process_id, lid, *browser_context_id, browser_context_dir, - max_file_size_bytes); + max_file_size_bytes, std::move(metadata)); } else { result = false; } @@ -495,15 +497,15 @@ int render_process_id, int lid, bool remote_logging_allowed, - const std::string& message, + const std::string message, base::OnceCallback<void(std::pair<bool, bool>)> reply) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); - const bool local_result = - local_logs_manager_.EventLogWrite(render_process_id, lid, message); + const bool local_result = local_logs_manager_.EventLogWrite( + render_process_id, lid, std::move(message)); const bool remote_result = - remote_logging_allowed - ? remote_logs_manager_.EventLogWrite(render_process_id, lid, message) - : false; + remote_logging_allowed ? remote_logs_manager_.EventLogWrite( + render_process_id, lid, std::move(message)) + : false; if (reply) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, @@ -550,7 +552,7 @@ } }; - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask(FROM_HERE, base::BindOnce(task, base::Unretained(this), clock, std::move(reply))); } @@ -569,7 +571,7 @@ } }; - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(task, base::Unretained(this), std::move(pc_tracker_proxy), std::move(reply))); @@ -593,7 +595,7 @@ } }; - // Posting to task queue owned by the unretained object - unretained is safe. + // The object outlives the task queue - base::Unretained(this) is safe. task_runner_->PostTask( FROM_HERE, base::BindOnce(task, base::Unretained(this), std::move(uploader_factory), std::move(reply)));
diff --git a/content/browser/webrtc/webrtc_event_log_manager.h b/content/browser/webrtc/webrtc_event_log_manager.h index 8f8d21a..7a17cec 100644 --- a/content/browser/webrtc/webrtc_event_log_manager.h +++ b/content/browser/webrtc/webrtc_event_log_manager.h
@@ -156,12 +156,15 @@ // posted back to BrowserThread::UI with the return value provided by // WebRtcRemoteEventLogManager::StartRemoteLogging - see the comment there // for more details. - // TODO(eladalon): Add support for injecting metadata through this call. - // https://crbug.com/775415 + // One may attach an arbitrary binary string |metadata|, which would be + // prepended to the WebRTC event log. Its length is counted towards the + // max file size. (I.e., if the metadata is of length 4 and the max size + // is 10, only 6 bytes are left available for the actual WebRTC event log.) void StartRemoteLogging( int render_process_id, int lid, // Renderer-local PeerConnection ID. size_t max_file_size_bytes, + const std::string& metadata = "", base::OnceCallback<void(bool)> reply = base::OnceCallback<void(bool)>()); // Called when a new log fragment is sent from the renderer. This will @@ -275,13 +278,14 @@ base::Optional<BrowserContextId> browser_context_id, const base::FilePath& browser_context_dir, size_t max_file_size_bytes, + const std::string metadata, base::OnceCallback<void(bool)> reply); void OnWebRtcEventLogWriteInternal( int render_process_id, int lid, // Renderer-local PeerConnection ID. bool remote_logging_allowed, - const std::string& message, + const std::string message, base::OnceCallback<void(std::pair<bool, bool>)> reply); void RenderProcessExitedInternal(int render_process_id);
diff --git a/content/browser/webrtc/webrtc_event_log_manager_common.cc b/content/browser/webrtc/webrtc_event_log_manager_common.cc index b3087b5..85d13f73 100644 --- a/content/browser/webrtc/webrtc_event_log_manager_common.cc +++ b/content/browser/webrtc/webrtc_event_log_manager_common.cc
@@ -25,7 +25,8 @@ log_file.file_size_bytes + message.length() > log_file.max_file_size_bytes; if (size_will_wrap_around || size_limit_will_be_exceeded) { - message_len = log_file.max_file_size_bytes - log_file.file_size_bytes; + CloseLogFile(it); + return false; } } @@ -45,9 +46,6 @@ } } - // Truncated message due to exceeding the maximum is reported as an error - - // the caller is interested to know that not all of its message was written, - // regardless of the reason. return (static_cast<size_t>(written) == message.length()); }
diff --git a/content/browser/webrtc/webrtc_event_log_manager_common.h b/content/browser/webrtc/webrtc_event_log_manager_common.h index 9c81392..93d5a6c 100644 --- a/content/browser/webrtc/webrtc_event_log_manager_common.h +++ b/content/browser/webrtc/webrtc_event_log_manager_common.h
@@ -45,6 +45,17 @@ // kept on local disk. CONTENT_EXPORT extern const base::FilePath::CharType kRemoteBoundLogExtension[]; +// Version of the remote-bound log. Refers to the version of the event logs' +// encoding, method for separation of metadata from the WebRTC event log, etc. +CONTENT_EXPORT extern const uint8_t kRemoteBoundWebRtcEventLogFileVersion; + +// Remote-bound log headers are composed of: +// * One byte for the version (for the encoding, metadata format, etc.) +// * Three bytes encoding the length of the metadata, in bytes. +// The metadata, which immediately follows the header, is not counted as part +// of the header size. +CONTENT_EXPORT extern const size_t kRemoteBoundLogFileHeaderSizeBytes; + // Remote-bound event logs will not be uploaded if the time since their last // modification (meaning the time when they were completed) exceeds this value. // Such expired files will be purged from disk when examined. @@ -105,11 +116,12 @@ struct LogFile { LogFile(const base::FilePath& path, base::File file, - size_t max_file_size_bytes) + size_t max_file_size_bytes, + size_t file_size_bytes = 0) : path(path), file(std::move(file)), max_file_size_bytes(max_file_size_bytes), - file_size_bytes(0) {} + file_size_bytes(file_size_bytes) {} const base::FilePath path; base::File file; const size_t max_file_size_bytes;
diff --git a/content/browser/webrtc/webrtc_event_log_manager_unittest.cc b/content/browser/webrtc/webrtc_event_log_manager_unittest.cc index 24655768a6..c16c97f 100644 --- a/content/browser/webrtc/webrtc_event_log_manager_unittest.cc +++ b/content/browser/webrtc/webrtc_event_log_manager_unittest.cc
@@ -13,6 +13,7 @@ #include <utility> #include <vector> +#include "base/big_endian.h" #include "base/bind.h" #include "base/files/file.h" #include "base/files/file_path.h" @@ -217,14 +218,22 @@ bool StartRemoteLogging(int render_process_id, int lid, - size_t max_size_bytes = kArbitraryVeryLargeFileSize) { + size_t max_size_bytes = kArbitraryVeryLargeFileSize, + const std::string& metadata = "") { bool result; manager_->StartRemoteLogging(render_process_id, lid, max_size_bytes, - BoolReplyClosure(&result)); + metadata, BoolReplyClosure(&result)); WaitForReply(); return result; } + bool StartRemoteLogging(int render_process_id, + int lid, + const std::string& metadata) { + return StartRemoteLogging(render_process_id, lid, + kArbitraryVeryLargeFileSize, metadata); + } + void SetLocalLogsObserver(WebRtcLocalEventLogsObserver* observer) { manager_->SetLocalLogsObserver(observer, VoidReplyClosure()); WaitForReply(); @@ -342,13 +351,43 @@ upload_suppressing_rph_.reset(); } - void ExpectFileContents(const base::FilePath& file_path, - const std::string& expected_contents) { + void ExpectLocalFileContents(const base::FilePath& file_path, + const std::string& expected_contents) { std::string file_contents; ASSERT_TRUE(base::ReadFileToString(file_path, &file_contents)); EXPECT_EQ(file_contents, expected_contents); } + void ExpectRemoteFileContents(const base::FilePath& file_path, + const std::string& expected_event_log, + const std::string& expected_metadata = "") { + std::string file_contents; + ASSERT_TRUE(base::ReadFileToString(file_path, &file_contents)); + + // Even an empty file must contain the header. + ASSERT_GE(file_contents.length(), kRemoteBoundLogFileHeaderSizeBytes); + + uint32_t header; + base::ReadBigEndian<uint32_t>(file_contents.c_str(), &header); + + // Make sure it's a supported version. + const uint8_t version = static_cast<uint8_t>(header >> 24); + EXPECT_EQ(version, kRemoteBoundWebRtcEventLogFileVersion); + + // Verify the metadata is as expected. + const uint32_t metadata_length = (header & 0xFFFFFFu); + ASSERT_LE(kRemoteBoundLogFileHeaderSizeBytes + metadata_length, + file_contents.size()); + const std::string metadata = file_contents.substr( + kRemoteBoundLogFileHeaderSizeBytes, metadata_length); + EXPECT_EQ(metadata, expected_metadata); + + // Verify the WebRTC event log itself. + const std::string event_log = file_contents.substr( + kRemoteBoundLogFileHeaderSizeBytes + metadata_length); + EXPECT_EQ(event_log, expected_event_log); + } + static const size_t kArbitraryVeryLargeFileSize = 1000 * 1000 * 1000; // Testing utilities. @@ -705,7 +744,7 @@ // Make sure the file would be closed, so that we could safely read it. ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); - ExpectFileContents(*file_path, ""); + ExpectLocalFileContents(*file_path, ""); } TEST_F(WebRtcEventLogManagerTest, LocalLogCreateAndWriteToFile) { @@ -727,7 +766,7 @@ // Make sure the file would be closed, so that we could safely read it. ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); - ExpectFileContents(*file_path, log); + ExpectLocalFileContents(*file_path, log); } TEST_F(WebRtcEventLogManagerTest, LocalLogMultipleWritesToSameFile) { @@ -754,7 +793,7 @@ // Make sure the file would be closed, so that we could safely read it. ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); - ExpectFileContents( + ExpectLocalFileContents( *file_path, std::accumulate(std::begin(logs), std::end(logs), std::string())); } @@ -774,10 +813,9 @@ ASSERT_TRUE(file_path); ASSERT_FALSE(file_path->empty()); - // A failure is reported, because not everything could be written. The file + // Failure is reported, because not everything could be written. The file // will also be closed. - const auto pc = PeerConnectionKey(key.render_process_id, key.lid); - EXPECT_CALL(local_observer_, OnLocalLogStopped(pc)).Times(1); + EXPECT_CALL(local_observer_, OnLocalLogStopped(key)).Times(1); ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, log), std::make_pair(false, false)); @@ -785,7 +823,7 @@ ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, "ignored"), std::make_pair(false, false)); - ExpectFileContents(*file_path, log.substr(0, file_size_limit_bytes)); + ExpectLocalFileContents(*file_path, ""); } TEST_F(WebRtcEventLogManagerTest, LocalLogSanityOverUnlimitedFileSizes) { @@ -810,7 +848,7 @@ // Make sure the file would be closed, so that we could safely read it. ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); - ExpectFileContents(*file_path, log1 + log2); + ExpectLocalFileContents(*file_path, log1 + log2); } TEST_F(WebRtcEventLogManagerTest, LocalLogNoWriteAfterLogStopped) { @@ -835,7 +873,7 @@ ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, log_after), std::make_pair(false, false)); - ExpectFileContents(*file_path, log_before); + ExpectLocalFileContents(*file_path, log_before); } TEST_F(WebRtcEventLogManagerTest, LocalLogOnlyWritesTheLogsAfterStarted) { @@ -867,7 +905,7 @@ // Make sure the file would be closed, so that we could safely read it. ASSERT_TRUE(PeerConnectionRemoved(rph_->GetID(), kPeerConnectionId)); - ExpectFileContents(*file_path, log2); + ExpectLocalFileContents(*file_path, log2); } // Note: This test also covers the scenario LocalLogExistingFilesNotOverwritten, @@ -893,7 +931,7 @@ } for (size_t i = 0; i < logs.size(); i++) { - ExpectFileContents(*file_paths[i], logs[i]); + ExpectLocalFileContents(*file_paths[i], logs[i]); } } @@ -932,7 +970,7 @@ ASSERT_TRUE(DisableLocalLogging()); for (size_t i = 0; i < keys.size(); i++) { - ExpectFileContents(*file_paths[i], logs[i]); + ExpectLocalFileContents(*file_paths[i], logs[i]); } } @@ -1076,7 +1114,7 @@ } ASSERT_TRUE(DisableLocalLogging()); - ExpectFileContents( + ExpectLocalFileContents( *file_path, std::accumulate(std::begin(logs), std::end(logs), std::string())); } @@ -1266,7 +1304,7 @@ ASSERT_TRUE(PeerConnectionAdded(rph_->GetID(), kPeerConnectionId)); ASSERT_TRUE(StartRemoteLogging(rph_->GetID(), kPeerConnectionId)); - ExpectFileContents(*file_path, ""); + ExpectRemoteFileContents(*file_path, ""); } TEST_F(WebRtcEventLogManagerTest, RemoteLogFileCreatedInCorrectDirectory) { @@ -1317,7 +1355,69 @@ EXPECT_EQ(OnWebRtcEventLogWrite(rph_->GetID(), kPeerConnectionId, log), std::make_pair(false, true)); - ExpectFileContents(*file_path, log); + ExpectRemoteFileContents(*file_path, log); +} + +TEST_F(WebRtcEventLogManagerTest, + RemoteBoundLogWithZeroLengthMetadataWrittenCorrectly) { + NiceMock<MockWebRtcRemoteEventLogsObserver> observer; + base::Optional<base::FilePath> file_path; + const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId); + EXPECT_CALL(observer, OnRemoteLogStarted(key, _)) + .Times(1) + .WillOnce(Invoke(SaveFilePathTo(&file_path))); + SetRemoteLogsObserver(&observer); + + ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid)); + + const std::string metadata = ""; + ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid, metadata)); + + const char* const output = "WebRTC event log"; + EXPECT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, output), + std::make_pair(false, true)); + + ExpectRemoteFileContents(*file_path, output, metadata); +} + +TEST_F(WebRtcEventLogManagerTest, + RemoteBoundLogWithNonZeroLengthMetadataWrittenCorrectly) { + NiceMock<MockWebRtcRemoteEventLogsObserver> observer; + base::Optional<base::FilePath> file_path; + const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId); + EXPECT_CALL(observer, OnRemoteLogStarted(key, _)) + .Times(1) + .WillOnce(Invoke(SaveFilePathTo(&file_path))); + SetRemoteLogsObserver(&observer); + + ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid)); + + const std::string metadata = "metadata"; + ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid, metadata)); + + const char* const output = "WebRTC event log"; + EXPECT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, output), + std::make_pair(false, true)); + + ExpectRemoteFileContents(*file_path, output, metadata); +} + +// The scenario RemoteBoundLogWithMaximumSizeLessThanMetadataDisallowed is +// subcase of this one, and therefore not explicitly tested. +TEST_F(WebRtcEventLogManagerTest, + RemoteBoundLogMetadataMustLeaveSomeRoomForWebRtcEventLog) { + StrictMock<MockWebRtcRemoteEventLogsObserver> observer; + EXPECT_CALL(observer, OnRemoteLogStarted(_, _)).Times(0); + SetRemoteLogsObserver(&observer); + + const PeerConnectionKey key(rph_->GetID(), kPeerConnectionId); + ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid)); + + const std::string metadata = "metadata"; + const size_t max_log_size = + kRemoteBoundLogFileHeaderSizeBytes + metadata.length(); + ASSERT_FALSE(StartRemoteLogging(key.render_process_id, key.lid, max_log_size, + metadata)); } TEST_F(WebRtcEventLogManagerTest, WriteToBothLocalAndRemoteFiles) { @@ -1349,9 +1449,8 @@ // Ensure the flushing of the file to disk before attempting to read them. ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); - for (base::Optional<base::FilePath> file_path : {local_path, remote_path}) { - ExpectFileContents(*file_path, log); - } + ExpectLocalFileContents(*local_path, log); + ExpectRemoteFileContents(*remote_path, log); } TEST_F(WebRtcEventLogManagerTest, MultipleWritesToSameRemoteBoundLogfile) { @@ -1375,7 +1474,7 @@ // Make sure the file would be closed, so that we could safely read it. ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); - ExpectFileContents( + ExpectRemoteFileContents( *file_path, std::accumulate(std::begin(logs), std::end(logs), std::string())); } @@ -1387,13 +1486,14 @@ .WillByDefault(Invoke(SaveFilePathTo(&file_path))); const std::string log = "tpyo"; - const size_t file_size_limit_bytes = log.length() / 2; + const size_t file_size_limit_bytes = + kRemoteBoundLogFileHeaderSizeBytes + (log.length() / 2); ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid)); ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid, file_size_limit_bytes)); - // A failure is reported, because not everything could be written. The file + // Failure is reported, because not everything could be written. The file // will also be closed. EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1); ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, log), @@ -1403,7 +1503,7 @@ ASSERT_EQ(OnWebRtcEventLogWrite(key.render_process_id, key.lid, "ignored"), std::make_pair(false, false)); - ExpectFileContents(*file_path, log.substr(0, file_size_limit_bytes)); + ExpectRemoteFileContents(*file_path, ""); } TEST_F(WebRtcEventLogManagerTest, @@ -1436,7 +1536,7 @@ } for (size_t i = 0; i < keys.size(); i++) { - ExpectFileContents(*file_paths[i], logs[i]); + ExpectRemoteFileContents(*file_paths[i], logs[i]); } } @@ -1480,41 +1580,36 @@ } for (size_t i = 0; i < keys.size(); i++) { - ExpectFileContents(*file_paths[i], logs[i]); + ExpectRemoteFileContents(*file_paths[i], logs[i]); } } TEST_F(WebRtcEventLogManagerTest, DifferentRemoteLogsMayHaveDifferentMaximums) { - const std::vector<PeerConnectionKey> keys = { - PeerConnectionKey(rph_->GetID(), 0), PeerConnectionKey(rph_->GetID(), 1)}; - std::vector<base::Optional<base::FilePath>> file_paths(keys.size()); - for (size_t i = 0; i < keys.size(); i++) { + const std::string logs[2] = {"abra", "cadabra"}; + std::vector<base::Optional<base::FilePath>> file_paths(arraysize(logs)); + std::vector<PeerConnectionKey> keys; + for (size_t i = 0; i < arraysize(logs); i++) { + keys.emplace_back(rph_->GetID(), i); ON_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _)) .WillByDefault(Invoke(SaveFilePathTo(&file_paths[i]))); } - const size_t file_size_limits_bytes[2] = {3, 5}; - CHECK_EQ(arraysize(file_size_limits_bytes), keys.size()); - - const std::string log = "lorem ipsum"; - for (size_t i = 0; i < keys.size(); i++) { ASSERT_TRUE(PeerConnectionAdded(keys[i].render_process_id, keys[i].lid)); - ASSERT_TRUE(StartRemoteLogging(keys[i].render_process_id, keys[i].lid, - file_size_limits_bytes[i])); - - ASSERT_LT(file_size_limits_bytes[i], log.length()); - - // A failure is reported, because not everything could be written. The file - // will also be closed. - ASSERT_EQ( - OnWebRtcEventLogWrite(keys[i].render_process_id, keys[i].lid, log), - std::make_pair(false, false)); + ASSERT_TRUE(StartRemoteLogging( + keys[i].render_process_id, keys[i].lid, + kRemoteBoundLogFileHeaderSizeBytes + logs[i].length())); } for (size_t i = 0; i < keys.size(); i++) { - ExpectFileContents(*file_paths[i], - log.substr(0, file_size_limits_bytes[i])); + // The write is successful, but the file closed, indicating that the maximum + // file size has been reached. + EXPECT_CALL(remote_observer_, OnRemoteLogStopped(keys[i])).Times(1); + ASSERT_EQ( + OnWebRtcEventLogWrite(keys[i].render_process_id, keys[i].lid, logs[i]), + std::make_pair(false, true)); + ASSERT_TRUE(file_paths[i]); + ExpectRemoteFileContents(*file_paths[i], logs[i]); } } @@ -1527,7 +1622,9 @@ const std::string log = "Let X equal X."; ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid)); - ASSERT_TRUE(StartRemoteLogging(key.render_process_id, key.lid, log.length())); + ASSERT_TRUE( + StartRemoteLogging(key.render_process_id, key.lid, + kRemoteBoundLogFileHeaderSizeBytes + log.length())); ASSERT_TRUE(file_path); EXPECT_CALL(remote_observer_, OnRemoteLogStopped(key)).Times(1); @@ -1628,7 +1725,8 @@ EXPECT_CALL(remote_observer_, OnRemoteLogStarted(PeerConnectionKey(rph_->GetID(), i), _)) .Times(1); - ASSERT_TRUE(StartRemoteLogging(rph_->GetID(), i, log.length())); + ASSERT_TRUE(StartRemoteLogging( + rph_->GetID(), i, kRemoteBoundLogFileHeaderSizeBytes + log.length())); } // By writing to one of the logs until it reaches capacity, we fill it, @@ -1977,7 +2075,7 @@ } ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); - ExpectFileContents( + ExpectRemoteFileContents( *file_path, std::accumulate(std::begin(logs), std::end(logs), std::string())); } @@ -2215,8 +2313,8 @@ // Make sure the file would be closed, so that we could safely read it. ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); - ExpectFileContents(*local_log_file_path, all_chars); - ExpectFileContents(*remote_log_file_path, all_chars); + ExpectLocalFileContents(*local_log_file_path, all_chars); + ExpectRemoteFileContents(*remote_log_file_path, all_chars); } TEST_F(WebRtcEventLogManagerTest, LocalLogsClosedWhenRenderProcessHostExits) {
diff --git a/content/browser/webrtc/webrtc_remote_event_log_manager.cc b/content/browser/webrtc/webrtc_remote_event_log_manager.cc index 02a811a..9f45c62 100644 --- a/content/browser/webrtc/webrtc_remote_event_log_manager.cc +++ b/content/browser/webrtc/webrtc_remote_event_log_manager.cc
@@ -4,12 +4,16 @@ #include "content/browser/webrtc/webrtc_remote_event_log_manager.h" +#include <limits> + +#include "base/big_endian.h" #include "base/bind.h" #include "base/files/file.h" #include "base/files/file_enumerator.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" +#include "base/macros.h" #include "base/rand_util.h" #include "base/threading/sequenced_task_runner_handle.h" #include "content/public/browser/browser_thread.h" @@ -22,6 +26,15 @@ namespace { const base::FilePath::CharType kRemoteBoundLogSubDirectory[] = FILE_PATH_LITERAL("webrtc_event_logs"); + +// Purge from local disk a log file which could not be properly started +// (e.g. error encountered when attempting to write the log header). +void DiscardLogFile(base::File* file, const base::FilePath& file_path) { + file->Close(); + if (!base::DeleteFile(file_path, /*recursive=*/false)) { + LOG(ERROR) << "Failed to delete " << file_path << "."; + } +} } // namespace const size_t kMaxActiveRemoteBoundWebRtcEventLogs = 3; @@ -36,6 +49,10 @@ const base::FilePath::CharType kRemoteBoundLogExtension[] = FILE_PATH_LITERAL("log"); +const uint8_t kRemoteBoundWebRtcEventLogFileVersion = 0; + +const size_t kRemoteBoundLogFileHeaderSizeBytes = sizeof(uint32_t); + WebRtcRemoteEventLogManager::WebRtcRemoteEventLogManager( WebRtcRemoteEventLogsObserver* observer) : observer_(observer), @@ -115,7 +132,8 @@ int lid, BrowserContextId browser_context, const base::FilePath& browser_context_dir, - size_t max_file_size_bytes) { + size_t max_file_size_bytes, + const std::string& metadata) { DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); // TODO(eladalon): Set a tighter limit (following discussion with rschriebman @@ -124,6 +142,18 @@ return false; } + if (metadata.length() > 0xFFFFFFu) { + // We use three bytes to encode the length of the metadata. + LOG(ERROR) << "Metadata must be less than 2^24 bytes."; + return false; + } + + if (metadata.size() + kRemoteBoundLogFileHeaderSizeBytes >= + max_file_size_bytes) { + LOG(ERROR) << "Max file size and metadata must leave room for event log."; + return false; + } + const PeerConnectionKey key(render_process_id, lid); // May not start logging inactive peer connections. @@ -157,7 +187,7 @@ } return StartWritingLog(render_process_id, lid, browser_context, - browser_context_dir, max_file_size_bytes); + browser_context_dir, max_file_size_bytes, metadata); } bool WebRtcRemoteEventLogManager::EventLogWrite(int render_process_id, @@ -316,9 +346,19 @@ int lid, BrowserContextId browser_context, const base::FilePath& browser_context_dir, - size_t max_file_size_bytes) { + size_t max_file_size_bytes, + const std::string& metadata) { DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + // WriteAtCurrentPos() only allows writing up to max-int at a time. We could + // iterate to do more, but we don't expect to ever need to, so it's easier + // to disallow it. + if (metadata.length() > + static_cast<size_t>(std::numeric_limits<int>::max())) { + LOG(WARNING) << "Metadata too long to be written in one go."; + return false; + } + // Randomize a new filename. In the highly unlikely event that this filename // is already taken, it will be treated the same way as any other failure // to start the log file. @@ -338,10 +378,35 @@ return false; } + const uint32_t header_host_order = + static_cast<uint32_t>(metadata.length()) | + (kRemoteBoundWebRtcEventLogFileVersion << 24); + static_assert(kRemoteBoundLogFileHeaderSizeBytes == sizeof(uint32_t), + "Restructure this otherwise."); + char header[sizeof(uint32_t)]; + base::WriteBigEndian<uint32_t>(header, header_host_order); + int written = file.WriteAtCurrentPos(header, arraysize(header)); + if (written != arraysize(header)) { + LOG(WARNING) << "Failed to write header to log file."; + DiscardLogFile(&file, file_path); + return false; + } + + const int metadata_length = static_cast<int>(metadata.length()); + written = file.WriteAtCurrentPos(metadata.c_str(), metadata_length); + if (written != metadata_length) { + LOG(WARNING) << "Failed to write metadata to log file."; + DiscardLogFile(&file, file_path); + return false; + } + // Record that we're now writing this remote-bound log to this file. const PeerConnectionKey key(render_process_id, lid); + const size_t header_and_metadata_size_bytes = + kRemoteBoundLogFileHeaderSizeBytes + metadata_length; const auto it = active_logs_.emplace( - key, LogFile(file_path, std::move(file), max_file_size_bytes)); + key, LogFile(file_path, std::move(file), max_file_size_bytes, + header_and_metadata_size_bytes)); DCHECK(it.second); active_logs_counts_[browser_context] += 1;
diff --git a/content/browser/webrtc/webrtc_remote_event_log_manager.h b/content/browser/webrtc/webrtc_remote_event_log_manager.h index c1c37657..e3da402e 100644 --- a/content/browser/webrtc/webrtc_remote_event_log_manager.h +++ b/content/browser/webrtc/webrtc_remote_event_log_manager.h
@@ -70,11 +70,14 @@ int lid, BrowserContextId browser_context, const base::FilePath& browser_context_dir, - size_t max_file_size_bytes); + size_t max_file_size_bytes, + const std::string& metadata); // If an active remote-bound log exists for the given peer connection, this - // will append |message| to that log. If writing |message| to the log would - // exceed its maximum allowed size, |message| is first truncated. + // will append |message| to that log. + // If writing |message| to the log would exceed the log's maximum allowed + // size, the write is disallowed and the file is closed instead (and changes + // from ACTIVE to PENDING). // If the log file's capacity is exhausted as a result of this function call, // or if a write error occurs, the file is closed, and the remote-bound log // changes from ACTIVE to PENDING. @@ -158,7 +161,8 @@ int lid, BrowserContextId browser_context, const base::FilePath& browser_context_dir, - size_t max_file_size_bytes); + size_t max_file_size_bytes, + const std::string& metadata); // Checks if the referenced peer connection has an associated active // remote-bound log. If it does, the log is changed from ACTIVE to PENDING.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 20802dc..787f136 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -574,7 +574,8 @@ const network::ResourceRequest& request, ResourceContext* resource_context, const base::RepeatingCallback<WebContents*()>& wc_getter, - NavigationUIData* navigation_ui_data) { + NavigationUIData* navigation_ui_data, + int frame_tree_node_id) { return std::vector<std::unique_ptr<URLLoaderThrottle>>(); }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index b5c7166a3..3302156 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -955,7 +955,8 @@ const network::ResourceRequest& request, ResourceContext* resource_context, const base::RepeatingCallback<WebContents*()>& wc_getter, - NavigationUIData* navigation_ui_data); + NavigationUIData* navigation_ui_data, + int frame_tree_node_id); // Allows the embedder to register per-scheme URLLoaderFactory implementations // to handle navigation URL requests for schemes not handled by the Network
diff --git a/content/public/browser/navigation_controller.cc b/content/public/browser/navigation_controller.cc index a6850f2..7967b0b0 100644 --- a/content/public/browser/navigation_controller.cc +++ b/content/public/browser/navigation_controller.cc
@@ -24,60 +24,11 @@ #endif has_user_gesture(false), should_clear_history_list(false), - started_from_context_menu(false) { + started_from_context_menu(false), + navigation_ui_data(nullptr) { } NavigationController::LoadURLParams::~LoadURLParams() { } -NavigationController::LoadURLParams::LoadURLParams( - const NavigationController::LoadURLParams& other) - : url(other.url), - load_type(other.load_type), - transition_type(other.transition_type), - frame_tree_node_id(other.frame_tree_node_id), - referrer(other.referrer), - extra_headers(other.extra_headers), - is_renderer_initiated(other.is_renderer_initiated), - override_user_agent(other.override_user_agent), - transferred_global_request_id(other.transferred_global_request_id), - base_url_for_data_url(other.base_url_for_data_url), - virtual_url_for_data_url(other.virtual_url_for_data_url), - post_data(other.post_data), - should_replace_current_entry(false), -#if defined(OS_ANDROID) - intent_received_timestamp(other.intent_received_timestamp), -#endif - has_user_gesture(other.has_user_gesture), - should_clear_history_list(false), - started_from_context_menu(other.started_from_context_menu) { -} - -NavigationController::LoadURLParams& -NavigationController::LoadURLParams::operator=( - const NavigationController::LoadURLParams& other) { - url = other.url; - load_type = other.load_type; - transition_type = other.transition_type; - frame_tree_node_id = other.frame_tree_node_id; - referrer = other.referrer; - redirect_chain = other.redirect_chain; - extra_headers = other.extra_headers; - is_renderer_initiated = other.is_renderer_initiated; - override_user_agent = other.override_user_agent; - transferred_global_request_id = other.transferred_global_request_id; - base_url_for_data_url = other.base_url_for_data_url; - virtual_url_for_data_url = other.virtual_url_for_data_url; - post_data = other.post_data; - should_replace_current_entry = other.should_replace_current_entry; - should_clear_history_list = other.should_clear_history_list; -#if defined(OS_ANDROID) - intent_received_timestamp = other.intent_received_timestamp; -#endif - has_user_gesture = other.has_user_gesture; - started_from_context_menu = other.started_from_context_menu; - - return *this; -} - } // namespace content
diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index aacd0d1c..a9633bb 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h
@@ -17,6 +17,7 @@ #include "build/build_config.h" #include "content/common/content_export.h" #include "content/public/browser/global_request_id.h" +#include "content/public/browser/navigation_ui_data.h" #include "content/public/browser/reload_type.h" #include "content/public/browser/restore_type.h" #include "content/public/browser/session_storage_namespace.h" @@ -199,12 +200,15 @@ // of that attribute. base::Optional<std::string> suggested_filename; + // This value should only be set for main frame navigations. Subframe + // navigations will always get their NavigationUIData from + // ContentBrowserClient::GetNavigationUIData. + std::unique_ptr<NavigationUIData> navigation_ui_data; + explicit LoadURLParams(const GURL& url); ~LoadURLParams(); - // Allows copying of LoadURLParams struct. - LoadURLParams(const LoadURLParams& other); - LoadURLParams& operator=(const LoadURLParams& other); + DISALLOW_COPY_AND_ASSIGN(LoadURLParams); }; // Disables checking for a repost and prompting the user. This is used during
diff --git a/content/public/browser/navigation_handle.cc b/content/public/browser/navigation_handle.cc index 84a4d77..a64826a 100644 --- a/content/public/browser/navigation_handle.cc +++ b/content/public/browser/navigation_handle.cc
@@ -50,6 +50,7 @@ CSPDisposition::CHECK, // should_check_main_world_csp false, // is_form_submission base::nullopt, // suggested_filename + nullptr, // navigation_ui_data method, resource_request_body, Referrer(), false, // has_user_gesture transition);
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h index 027c70a..5a51e9b 100644 --- a/content/public/browser/navigation_handle.h +++ b/content/public/browser/navigation_handle.h
@@ -29,6 +29,7 @@ struct GlobalRequestID; class NavigationData; class NavigationThrottle; +class NavigationUIData; class RenderFrameHost; class SiteInstance; class WebContents; @@ -145,6 +146,9 @@ // Returns the page transition type. virtual ui::PageTransition GetPageTransition() = 0; + // Returns the NavigationUIData associated with the navigation. + virtual const NavigationUIData* GetNavigationUIData() = 0; + // Whether the target URL cannot be handled by the browser's internal protocol // handlers. virtual bool IsExternalProtocol() = 0;
diff --git a/content/public/browser/web_contents_view_delegate.cc b/content/public/browser/web_contents_view_delegate.cc index 5d86aae..3d0a1bf 100644 --- a/content/public/browser/web_contents_view_delegate.cc +++ b/content/public/browser/web_contents_view_delegate.cc
@@ -41,6 +41,9 @@ return false; } +void WebContentsViewDelegate::SizeChanged(const gfx::Size& size) { +} + void WebContentsViewDelegate::OverrideDisplayColorSpace( gfx::ColorSpace* color_space) {}
diff --git a/content/public/browser/web_contents_view_delegate.h b/content/public/browser/web_contents_view_delegate.h index 6b29450..b7a1112 100644 --- a/content/public/browser/web_contents_view_delegate.h +++ b/content/public/browser/web_contents_view_delegate.h
@@ -19,6 +19,7 @@ namespace gfx { class ColorSpace; +class Size; } namespace content { @@ -60,6 +61,9 @@ // Advance focus to the view that follows or precedes the WebContents. virtual bool TakeFocus(bool reverse); + // Allows the delegate to update bounds for a special views. + virtual void SizeChanged(const gfx::Size& size); + // This method allows the embedder to specify the display color space (instead // of using the color space specified by display::Display) and write it in // |*color_space|. The default behavior is to leave |*color_space| unchanged.
diff --git a/content/public/test/test_navigation_ui_data.cc b/content/public/test/test_navigation_ui_data.cc new file mode 100644 index 0000000..cc442c3 --- /dev/null +++ b/content/public/test/test_navigation_ui_data.cc
@@ -0,0 +1,15 @@ +// 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. + +#include "content/public/test/test_navigation_ui_data.h" + +#include <memory> + +namespace content { + +std::unique_ptr<NavigationUIData> TestNavigationUIData::Clone() const { + return std::make_unique<TestNavigationUIData>(); +} + +} // namespace content
diff --git a/content/public/test/test_navigation_ui_data.h b/content/public/test/test_navigation_ui_data.h new file mode 100644 index 0000000..1d57d0f --- /dev/null +++ b/content/public/test/test_navigation_ui_data.h
@@ -0,0 +1,26 @@ +// 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. + +#ifndef CONTENT_PUBLIC_TEST_TEST_NAVIGATION_UI_DATA_H_ +#define CONTENT_PUBLIC_TEST_TEST_NAVIGATION_UI_DATA_H_ + +#include <memory> + +#include "content/public/browser/navigation_ui_data.h" + +namespace content { + +// Subclass for content tests to check NavigationUIData is passed around +// correctly. +class TestNavigationUIData : public content::NavigationUIData { + public: + TestNavigationUIData() {} + ~TestNavigationUIData() override {} + + std::unique_ptr<NavigationUIData> Clone() const override; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_TEST_TEST_NAVIGATION_UI_DATA_H_
diff --git a/content/renderer/media/gpu/rtc_video_decoder.cc b/content/renderer/media/gpu/rtc_video_decoder.cc index c0756fb..48202fd 100644 --- a/content/renderer/media/gpu/rtc_video_decoder.cc +++ b/content/renderer/media/gpu/rtc_video_decoder.cc
@@ -421,9 +421,8 @@ // Create a WebRTC video frame. webrtc::VideoFrame decoded_image( - new rtc::RefCountedObject<WebRtcVideoFrameAdapter>( - frame, WebRtcVideoFrameAdapter::CopyTextureFrameCallback()), - timestamp, 0, webrtc::kVideoRotation_0); + new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame), timestamp, 0, + webrtc::kVideoRotation_0); // Invoke decode callback. WebRTC expects no callback after Release. {
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc index b5eaa24..9982c25 100644 --- a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
@@ -5,19 +5,12 @@ #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" #include "base/bind.h" -#include "base/memory/ref_counted.h" -#include "base/synchronization/waitable_event.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "cc/paint/skia_paint_canvas.h" #include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h" -#include "content/renderer/render_thread_impl.h" #include "media/base/timestamp_constants.h" #include "media/base/video_util.h" -#include "media/renderers/paint_canvas_video_renderer.h" -#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" -#include "skia/ext/platform_canvas.h" -#include "third_party/libyuv/include/libyuv/convert.h" #include "third_party/libyuv/include/libyuv/convert_from.h" #include "third_party/libyuv/include/libyuv/scale.h" #include "third_party/webrtc/api/video/video_rotation.h" @@ -32,127 +25,12 @@ void CapturerReleaseOriginalFrame( const scoped_refptr<media::VideoFrame>& frame) {} -// Helper class that signals a WaitableEvent when it goes out of scope. -class ScopedWaitableEvent { - public: - explicit ScopedWaitableEvent(base::WaitableEvent* event) : event_(event) {} - ~ScopedWaitableEvent() { - if (event_) - event_->Signal(); - } - - private: - base::WaitableEvent* const event_; -}; - } // anonymous namespace -// Initializes the GL context environment and provides a method for copying -// texture backed frames into CPU mappable memory. -// The class is created and destroyed on the main render thread. -class WebRtcVideoCapturerAdapter::TextureFrameCopier - : public base::RefCounted<WebRtcVideoCapturerAdapter::TextureFrameCopier> { - public: - TextureFrameCopier() - : main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), - canvas_video_renderer_(new media::PaintCanvasVideoRenderer) { - RenderThreadImpl* const main_thread = RenderThreadImpl::current(); - if (main_thread) - provider_ = main_thread->SharedMainThreadContextProvider(); - } - - // Synchronous call to copy a texture backed |frame| into a CPU mappable - // |new_frame|. If it is not called on the main render thread, this call posts - // a task on main thread by calling CopyTextureFrameOnMainThread() and blocks - // until it is completed. - void CopyTextureFrame(const scoped_refptr<media::VideoFrame>& frame, - scoped_refptr<media::VideoFrame>* new_frame) { - if (main_thread_task_runner_->BelongsToCurrentThread()) { - CopyTextureFrameOnMainThread(frame, new_frame, nullptr); - return; - } - - base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - main_thread_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&TextureFrameCopier::CopyTextureFrameOnMainThread, this, - frame, new_frame, &waiter)); - waiter.Wait(); - } - - private: - friend class base::RefCounted<TextureFrameCopier>; - ~TextureFrameCopier() { - // |canvas_video_renderer_| should be deleted on the thread it was created. - if (!main_thread_task_runner_->BelongsToCurrentThread()) { - main_thread_task_runner_->DeleteSoon(FROM_HERE, - canvas_video_renderer_.release()); - } - } - - void CopyTextureFrameOnMainThread( - const scoped_refptr<media::VideoFrame>& frame, - scoped_refptr<media::VideoFrame>* new_frame, - base::WaitableEvent* waiter) { - DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); - DCHECK(frame->format() == media::PIXEL_FORMAT_ARGB || - frame->format() == media::PIXEL_FORMAT_XRGB || - frame->format() == media::PIXEL_FORMAT_I420 || - frame->format() == media::PIXEL_FORMAT_UYVY || - frame->format() == media::PIXEL_FORMAT_NV12); - ScopedWaitableEvent event(waiter); - - if (!provider_) { - // Return a black frame (yuv = {0, 0x80, 0x80}). - *new_frame = media::VideoFrame::CreateColorFrame( - frame->visible_rect().size(), 0u, 0x80, 0x80, frame->timestamp()); - return; - } - - SkBitmap bitmap; - bitmap.allocPixels(SkImageInfo::MakeN32Premul( - frame->visible_rect().width(), frame->visible_rect().height())); - cc::SkiaPaintCanvas paint_canvas(bitmap); - - *new_frame = media::VideoFrame::CreateFrame( - media::PIXEL_FORMAT_I420, frame->coded_size(), frame->visible_rect(), - frame->natural_size(), frame->timestamp()); - DCHECK(provider_->ContextGL()); - canvas_video_renderer_->Copy( - frame.get(), &paint_canvas, - media::Context3D(provider_->ContextGL(), provider_->GrContext())); - - SkPixmap pixmap; - const bool result = bitmap.peekPixels(&pixmap); - DCHECK(result) << "Error trying to access SkBitmap's pixels"; - const uint32 source_pixel_format = - (kN32_SkColorType == kRGBA_8888_SkColorType) ? cricket::FOURCC_ABGR - : cricket::FOURCC_ARGB; - libyuv::ConvertToI420( - static_cast<const uint8*>(pixmap.addr(0, 0)), pixmap.computeByteSize(), - (*new_frame)->visible_data(media::VideoFrame::kYPlane), - (*new_frame)->stride(media::VideoFrame::kYPlane), - (*new_frame)->visible_data(media::VideoFrame::kUPlane), - (*new_frame)->stride(media::VideoFrame::kUPlane), - (*new_frame)->visible_data(media::VideoFrame::kVPlane), - (*new_frame)->stride(media::VideoFrame::kVPlane), 0 /* crop_x */, - 0 /* crop_y */, pixmap.width(), pixmap.height(), - (*new_frame)->visible_rect().width(), - (*new_frame)->visible_rect().height(), libyuv::kRotate0, - source_pixel_format); - } - - const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; - scoped_refptr<ui::ContextProviderCommandBuffer> provider_; - std::unique_ptr<media::PaintCanvasVideoRenderer> canvas_video_renderer_; -}; - WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter( bool is_screencast, blink::WebMediaStreamTrack::ContentHintType content_hint) - : texture_copier_(new WebRtcVideoCapturerAdapter::TextureFrameCopier()), - is_screencast_(is_screencast), + : is_screencast_(is_screencast), content_hint_(content_hint), running_(false) { thread_checker_.DetachFromThread(); @@ -203,9 +81,7 @@ // cropping support for texture yet. See http://crbug/503653. if (frame->HasTextures()) { OnFrame(webrtc::VideoFrame( - new rtc::RefCountedObject<WebRtcVideoFrameAdapter>( - frame, base::Bind(&TextureFrameCopier::CopyTextureFrame, - texture_copier_)), + new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame), webrtc::kVideoRotation_0, translated_camera_time_us), orig_width, orig_height); return; @@ -233,9 +109,7 @@ // If no scaling is needed, return a wrapped version of |frame| directly. if (video_frame->natural_size() == video_frame->visible_rect().size()) { OnFrame(webrtc::VideoFrame( - new rtc::RefCountedObject<WebRtcVideoFrameAdapter>( - video_frame, - WebRtcVideoFrameAdapter::CopyTextureFrameCallback()), + new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(video_frame), webrtc::kVideoRotation_0, translated_camera_time_us), orig_width, orig_height); return; @@ -274,9 +148,7 @@ } OnFrame(webrtc::VideoFrame( - new rtc::RefCountedObject<WebRtcVideoFrameAdapter>( - scaled_frame, - WebRtcVideoFrameAdapter::CopyTextureFrameCallback()), + new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(scaled_frame), webrtc::kVideoRotation_0, translated_camera_time_us), orig_width, orig_height); }
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h index 4e5c55d..bd81bff0 100644 --- a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h
@@ -58,10 +58,6 @@ bool ShouldAdaptResolution() const; - // Helper class used for copying texture backed frames. - class TextureFrameCopier; - const scoped_refptr<TextureFrameCopier> texture_copier_; - // |thread_checker_| is bound to the libjingle worker thread. base::ThreadChecker thread_checker_;
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc b/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc index 2133e8a..e076b3d 100644 --- a/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc
@@ -4,21 +4,13 @@ #include <algorithm> -#include "base/bind.h" -#include "base/optional.h" #include "base/single_thread_task_runner.h" #include "base/test/scoped_task_environment.h" -#include "content/child/child_process.h" #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" #include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h" -#include "gpu/command_buffer/common/mailbox_holder.h" #include "media/base/video_frame.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { -static void ReleaseMailboxCB(const gpu::SyncToken& sync_token) {} -} // anonymous namespace - namespace content { class WebRtcVideoCapturerAdapterTest @@ -26,9 +18,7 @@ public ::testing::Test { public: WebRtcVideoCapturerAdapterTest() - : scoped_task_environment_( - base::test::ScopedTaskEnvironment::MainThreadType::IO), - adapter_(new WebRtcVideoCapturerAdapter( + : adapter_(new WebRtcVideoCapturerAdapter( false, blink::WebMediaStreamTrack::ContentHintType::kNone)), output_frame_width_(0), @@ -57,37 +47,8 @@ EXPECT_EQ(natural_height, output_frame_height_); } - void TestSourceTextureFrame() { - EXPECT_TRUE(scoped_task_environment_.GetMainThreadTaskRunner() - ->BelongsToCurrentThread()); - gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes] = { - gpu::MailboxHolder(gpu::Mailbox::Generate(), gpu::SyncToken(), 5)}; - scoped_refptr<media::VideoFrame> frame = - media::VideoFrame::WrapNativeTextures( - media::PIXEL_FORMAT_ARGB, holders, base::Bind(&ReleaseMailboxCB), - gfx::Size(10, 10), gfx::Rect(10, 10), gfx::Size(10, 10), - base::TimeDelta()); - adapter_->OnFrameCaptured(frame); - ASSERT_TRUE(output_frame_); - rtc::scoped_refptr<webrtc::VideoFrameBuffer> texture_frame = - output_frame_->video_frame_buffer(); - EXPECT_EQ(webrtc::VideoFrameBuffer::Type::kNative, texture_frame->type()); - EXPECT_EQ(media::VideoFrame::STORAGE_OPAQUE, - static_cast<WebRtcVideoFrameAdapter*>(texture_frame.get()) - ->getMediaVideoFrame() - ->storage_type()); - - rtc::scoped_refptr<webrtc::I420BufferInterface> copied_frame = - texture_frame->ToI420(); - EXPECT_TRUE(copied_frame); - EXPECT_TRUE(copied_frame->DataY()); - EXPECT_TRUE(copied_frame->DataU()); - EXPECT_TRUE(copied_frame->DataV()); - } - // rtc::VideoSinkInterface void OnFrame(const webrtc::VideoFrame& frame) override { - output_frame_ = base::Optional<webrtc::VideoFrame>(frame); output_frame_width_ = frame.width(); output_frame_height_ = frame.height(); } @@ -139,13 +100,7 @@ } private: - // The ScopedTaskEnvironment prevents the ChildProcess from leaking a - // TaskScheduler. - base::test::ScopedTaskEnvironment scoped_task_environment_; - const ChildProcess child_process_; - std::unique_ptr<WebRtcVideoCapturerAdapter> adapter_; - base::Optional<webrtc::VideoFrame> output_frame_; int output_frame_width_; int output_frame_height_; }; @@ -162,10 +117,6 @@ TestSourceCropFrame(1280, 720, 1280, 720, 640, 360); } -TEST_F(WebRtcVideoCapturerAdapterTest, SendsWithCopyTextureFrameCallback) { - TestSourceTextureFrame(); -} - TEST_F(WebRtcVideoCapturerAdapterTest, NonScreencastAdapterDoesNotAdaptContentHintDetail) { // Non-screenshare adapter should not adapt frames when detail is set.
diff --git a/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc b/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc index d65c73fa..bfa7ba1 100644 --- a/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc +++ b/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc
@@ -86,9 +86,8 @@ namespace content { WebRtcVideoFrameAdapter::WebRtcVideoFrameAdapter( - const scoped_refptr<media::VideoFrame>& frame, - const CopyTextureFrameCallback& copy_texture_callback) - : frame_(frame), copy_texture_callback_(copy_texture_callback) {} + const scoped_refptr<media::VideoFrame>& frame) + : frame_(frame) {} WebRtcVideoFrameAdapter::~WebRtcVideoFrameAdapter() { } @@ -107,17 +106,14 @@ rtc::scoped_refptr<webrtc::I420BufferInterface> WebRtcVideoFrameAdapter::ToI420() { + // We cant convert texture synchronously due to threading issues, see + // https://crbug.com/663452. Instead, return a black frame (yuv = {0, 0x80, + // 0x80}). if (frame_->HasTextures()) { - if (copy_texture_callback_.is_null()) { - DLOG(ERROR) << "Texture backed frame cannot be copied."; - return nullptr; - } - - scoped_refptr<media::VideoFrame> new_frame; - copy_texture_callback_.Run(frame_, &new_frame); - if (!new_frame) - return nullptr; - frame_ = new_frame; + DLOG(ERROR) << "Texture backed frame cannot be accessed."; + return new rtc::RefCountedObject<FrameAdapter<webrtc::I420BufferInterface>>( + media::VideoFrame::CreateColorFrame(frame_->visible_rect().size(), 0u, + 0x80, 0x80, frame_->timestamp())); } IsValidFrame(frame_);
diff --git a/content/renderer/media/webrtc/webrtc_video_frame_adapter.h b/content/renderer/media/webrtc/webrtc_video_frame_adapter.h index 1f1f836..e20b215c 100644 --- a/content/renderer/media/webrtc/webrtc_video_frame_adapter.h +++ b/content/renderer/media/webrtc/webrtc_video_frame_adapter.h
@@ -7,7 +7,6 @@ #include <stdint.h> -#include "base/callback.h" #include "media/base/video_frame.h" #include "third_party/webrtc/api/video/video_frame_buffer.h" @@ -18,13 +17,7 @@ // different threads, but that's safe since it's read-only. class WebRtcVideoFrameAdapter : public webrtc::VideoFrameBuffer { public: - using CopyTextureFrameCallback = - base::Callback<void(const scoped_refptr<media::VideoFrame>&, - scoped_refptr<media::VideoFrame>*)>; - - WebRtcVideoFrameAdapter( - const scoped_refptr<media::VideoFrame>& frame, - const CopyTextureFrameCallback& copy_texture_callback); + WebRtcVideoFrameAdapter(const scoped_refptr<media::VideoFrame>& frame); scoped_refptr<media::VideoFrame> getMediaVideoFrame() const { return frame_; } @@ -39,7 +32,6 @@ ~WebRtcVideoFrameAdapter() override; scoped_refptr<media::VideoFrame> frame_; - const CopyTextureFrameCallback copy_texture_callback_; }; } // namespace content
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index c2ded32..ff04c35 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -143,6 +143,8 @@ "../public/test/test_navigation_throttle.h", "../public/test/test_navigation_throttle_inserter.cc", "../public/test/test_navigation_throttle_inserter.h", + "../public/test/test_navigation_ui_data.cc", + "../public/test/test_navigation_ui_data.h", "../public/test/test_notification_tracker.cc", "../public/test/test_notification_tracker.h", "../public/test/test_renderer_host.cc", @@ -1575,6 +1577,7 @@ "../renderer/loader/url_response_body_consumer_unittest.cc", "../renderer/loader/web_data_consumer_handle_impl_unittest.cc", "../renderer/loader/web_url_loader_impl_unittest.cc", + "../renderer/manifest/manifest_parser_unittest.cc", "../renderer/media/audio_message_filter_unittest.cc", "../renderer/media/audio_output_ipc_factory_unittest.cc", "../renderer/media/audio_renderer_mixer_manager_unittest.cc",
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index c78a5139..82263a3 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -34,6 +34,9 @@ # Linux NVIDIA Quadro P400. LINUX_QUADRO_P400_STABLE_DRIVER = '10de:1cb3-384.90' +# Intel HD 630 (both Windows and Linux). +INTEL_HD_630 = '8086:5912' + # "Types" of waterfalls and bots. A bot's type is the union of its own # type and the type of its waterfall. Predicates can apply to these # sets in order to run tests only on a certain subset of the bots. @@ -384,7 +387,7 @@ 'Win10 Release (Intel HD 630)': { 'swarming_dimensions': [ { - 'gpu': '8086:5912', + 'gpu': INTEL_HD_630, 'os': 'Windows-10', 'pool': 'Chrome-GPU', }, @@ -656,7 +659,7 @@ 'Linux Release (Intel HD 630)': { 'swarming_dimensions': [ { - 'gpu': '8086:5912', + 'gpu': INTEL_HD_630, 'os': 'Ubuntu', 'pool': 'Chrome-GPU', }, @@ -823,6 +826,19 @@ 'type': Types.OPTIONAL, 'use_gpu_trigger_script': True, }, + 'Optional Win10 Release (Intel HD 630)': { + 'swarming_dimensions': [ + { + 'gpu': INTEL_HD_630, + 'os': 'Windows-10', + 'pool': 'Chrome-GPU', + }, + ], + 'build_config': 'Release', + 'swarming': True, + 'os_type': 'win', + 'type': Types.OPTIONAL, + }, 'Optional Mac Release (Intel)': { 'swarming_dimensions': [ { @@ -876,6 +892,19 @@ 'os_type': 'linux', 'type': Types.OPTIONAL, }, + 'Optional Linux Release (Intel HD 630)': { + 'swarming_dimensions': [ + { + 'gpu': INTEL_HD_630, + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], + 'build_config': 'Release', + 'swarming': True, + 'os_type': 'linux', + 'type': Types.OPTIONAL, + }, # This tryserver doesn't actually exist; it's a separate # configuration from the Win AMD bot on this waterfall because we # don't have enough tryserver capacity to run all the tests from
diff --git a/docs/speed/apk_size_regressions.md b/docs/speed/apk_size_regressions.md index fbf05e0d..b32310a 100644 --- a/docs/speed/apk_size_regressions.md +++ b/docs/speed/apk_size_regressions.md
@@ -29,6 +29,9 @@ tools/binary_size/diagnose_bloat.py AFTER_GIT_REV --reference-rev BEFORE_GIT_REV --subrepo v8 --all +You can usually find the before and after revs in the roll commit message +([example](https://chromium.googlesource.com/chromium/src/+/10c40fd863f4ae106650bba93b845f25c9b733b1)) + ### Monochrome.apk Alerts * The regression most likely already occurred in the upstream
diff --git a/extensions/browser/api/socket/socket.h b/extensions/browser/api/socket/socket.h index ed6b539..ca53df612 100644 --- a/extensions/browser/api/socket/socket.h +++ b/extensions/browser/api/socket/socket.h
@@ -81,7 +81,9 @@ // |socket_destroying| is true if disconnect is due to destruction of the // socket. virtual void Disconnect(bool socket_destroying) = 0; - virtual int Bind(const std::string& address, uint16_t port) = 0; + virtual void Bind(const std::string& address, + uint16_t port, + const CompletionCallback& callback) = 0; // The |callback| will be called with the number of bytes read into the // buffer, or a negative number if an error occurred. @@ -131,7 +133,6 @@ virtual int WriteImpl(net::IOBuffer* io_buffer, int io_buffer_size, const net::CompletionCallback& callback) = 0; - virtual void OnWriteComplete(int result); std::string hostname_; bool is_connected_; @@ -151,6 +152,9 @@ CompletionCallback callback; int bytes_written; }; + + void OnWriteComplete(int result); + base::queue<WriteRequest> write_queue_; scoped_refptr<net::IOBuffer> io_buffer_write_;
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc index e38af3f..cc2a6ca2 100644 --- a/extensions/browser/api/socket/socket_api.cc +++ b/extensions/browser/api/socket/socket_api.cc
@@ -234,9 +234,17 @@ case extensions::api::socket::SOCKET_TYPE_TCP: socket_type_ = kSocketTypeTCP; break; - case extensions::api::socket::SOCKET_TYPE_UDP: + case extensions::api::socket::SOCKET_TYPE_UDP: { socket_type_ = kSocketTypeUDP; + + network::mojom::UDPSocketReceiverPtr receiver_ptr; + socket_receiver_request_ = mojo::MakeRequest(&receiver_ptr); + content::BrowserContext::GetDefaultStoragePartition(browser_context()) + ->GetNetworkContext() + ->CreateUDPSocket(mojo::MakeRequest(&socket_), + std::move(receiver_ptr)); break; + } case extensions::api::socket::SOCKET_TYPE_NONE: NOTREACHED(); break; @@ -250,7 +258,9 @@ if (socket_type_ == kSocketTypeTCP) { socket = new TCPSocket(extension_->id()); } else if (socket_type_ == kSocketTypeUDP) { - socket = new UDPSocket(extension_->id()); + socket = + new UDPSocket(std::move(socket_), std::move(socket_receiver_request_), + extension_->id()); } DCHECK(socket); @@ -264,7 +274,9 @@ return true; } -void SocketDestroyFunction::Work() { RemoveSocket(socket_id_); } +void SocketDestroyFunction::Work() { + RemoveSocket(socket_id_); +} SocketConnectFunction::SocketConnectFunction() : socket_id_(0), hostname_(), port_(0) { @@ -341,7 +353,7 @@ } socket->Connect(addresses_, - base::Bind(&SocketConnectFunction::OnConnect, this)); + base::BindRepeating(&SocketConnectFunction::OnConnect, this)); } void SocketConnectFunction::OnConnect(int result) { @@ -403,9 +415,20 @@ return; } - int result = socket->Bind(address_, port_); - SetResult(std::make_unique<base::Value>(result)); - if (result != net::OK) { + socket->Bind(address_, port_, + base::BindRepeating(&SocketBindFunction::OnCompleted, this)); +} +void SocketBindFunction::OnCompleted(int net_result) { + Socket* socket = GetSocket(socket_id_); + if (!socket) { + error_ = kSocketNotFoundError; + SetResult(std::make_unique<base::Value>(-1)); + AsyncWorkCompleted(); + return; + } + + SetResult(std::make_unique<base::Value>(net_result)); + if (net_result != net::OK) { AsyncWorkCompleted(); return; } @@ -508,7 +531,7 @@ } socket->Read(params_->buffer_size.get() ? *params_->buffer_size : 4096, - base::Bind(&SocketReadFunction::OnCompleted, this)); + base::BindRepeating(&SocketReadFunction::OnCompleted, this)); } void SocketReadFunction::OnCompleted(int bytes_read, @@ -557,9 +580,8 @@ return; } - socket->Write(io_buffer_, - io_buffer_size_, - base::Bind(&SocketWriteFunction::OnCompleted, this)); + socket->Write(io_buffer_, io_buffer_size_, + base::BindRepeating(&SocketWriteFunction::OnCompleted, this)); } void SocketWriteFunction::OnCompleted(int bytes_written) { @@ -588,8 +610,9 @@ return; } - socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096, - base::Bind(&SocketRecvFromFunction::OnCompleted, this)); + socket->RecvFrom( + params_->buffer_size.get() ? *params_->buffer_size : 4096, + base::BindRepeating(&SocketRecvFromFunction::OnCompleted, this)); } void SocketRecvFromFunction::OnCompleted(int bytes_read, @@ -689,7 +712,7 @@ } socket->SendTo(io_buffer_, io_buffer_size_, addresses_.front(), - base::Bind(&SocketSendToFunction::OnCompleted, this)); + base::BindRepeating(&SocketSendToFunction::OnCompleted, this)); } void SocketSendToFunction::OnCompleted(int bytes_written) { @@ -852,18 +875,20 @@ return true; } -void SocketJoinGroupFunction::Work() { +void SocketJoinGroupFunction::AsyncWorkStart() { int result = -1; Socket* socket = GetSocket(params_->socket_id); if (!socket) { error_ = kSocketNotFoundError; SetResult(std::make_unique<base::Value>(result)); + AsyncWorkCompleted(); return; } if (socket->GetSocketType() != Socket::TYPE_UDP) { error_ = kMulticastSocketTypeError; SetResult(std::make_unique<base::Value>(result)); + AsyncWorkCompleted(); return; } @@ -876,14 +901,21 @@ APIPermission::kSocket, ¶m)) { error_ = kPermissionError; SetResult(std::make_unique<base::Value>(result)); + AsyncWorkCompleted(); return; } - result = static_cast<UDPSocket*>(socket)->JoinGroup(params_->address); - if (result != 0) { + static_cast<UDPSocket*>(socket)->JoinGroup( + params_->address, + base::BindRepeating(&SocketJoinGroupFunction::OnCompleted, this)); +} + +void SocketJoinGroupFunction::OnCompleted(int result) { + if (result != net::OK) { error_ = net::ErrorToString(result); } SetResult(std::make_unique<base::Value>(result)); + AsyncWorkCompleted(); } SocketLeaveGroupFunction::SocketLeaveGroupFunction() {} @@ -896,19 +928,21 @@ return true; } -void SocketLeaveGroupFunction::Work() { +void SocketLeaveGroupFunction::AsyncWorkStart() { int result = -1; Socket* socket = GetSocket(params_->socket_id); if (!socket) { error_ = kSocketNotFoundError; SetResult(std::make_unique<base::Value>(result)); + AsyncWorkCompleted(); return; } if (socket->GetSocketType() != Socket::TYPE_UDP) { error_ = kMulticastSocketTypeError; SetResult(std::make_unique<base::Value>(result)); + AsyncWorkCompleted(); return; } @@ -920,13 +954,20 @@ APIPermission::kSocket, ¶m)) { error_ = kPermissionError; SetResult(std::make_unique<base::Value>(result)); + AsyncWorkCompleted(); return; } - result = static_cast<UDPSocket*>(socket)->LeaveGroup(params_->address); - if (result != 0) + static_cast<UDPSocket*>(socket)->LeaveGroup( + params_->address, + base::BindRepeating(&SocketLeaveGroupFunction::OnCompleted, this)); +} + +void SocketLeaveGroupFunction::OnCompleted(int result) { + if (result != net::OK) error_ = net::ErrorToString(result); SetResult(std::make_unique<base::Value>(result)); + AsyncWorkCompleted(); } SocketSetMulticastTimeToLiveFunction::SocketSetMulticastTimeToLiveFunction() {}
diff --git a/extensions/browser/api/socket/socket_api.h b/extensions/browser/api/socket/socket_api.h index 28a6d29..a695f2f 100644 --- a/extensions/browser/api/socket/socket_api.h +++ b/extensions/browser/api/socket/socket_api.h
@@ -22,6 +22,8 @@ #include "net/base/network_change_notifier.h" #include "net/dns/host_resolver.h" #include "net/socket/tcp_client_socket.h" +#include "services/network/public/interfaces/network_service.mojom.h" +#include "services/network/public/interfaces/udp_socket.mojom.h" #if defined(OS_CHROMEOS) #include "extensions/browser/api/socket/app_firewall_hole_manager.h" @@ -183,6 +185,8 @@ FRIEND_TEST_ALL_PREFIXES(SocketUnitTest, Create); enum SocketType { kSocketTypeInvalid = -1, kSocketTypeTCP, kSocketTypeUDP }; + network::mojom::UDPSocketPtrInfo socket_; + network::mojom::UDPSocketReceiverRequest socket_receiver_request_; std::unique_ptr<api::socket::Create::Params> params_; SocketType socket_type_; }; @@ -254,6 +258,8 @@ void AsyncWorkStart() override; private: + void OnCompleted(int net_error); + int socket_id_; std::string address_; uint16_t port_; @@ -460,9 +466,11 @@ // AsyncApiFunction bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(int result); + std::unique_ptr<api::socket::JoinGroup::Params> params_; }; @@ -477,9 +485,11 @@ // AsyncApiFunction bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(int result); + std::unique_ptr<api::socket::LeaveGroup::Params> params_; };
diff --git a/extensions/browser/api/socket/tcp_socket.cc b/extensions/browser/api/socket/tcp_socket.cc index bed0d90..a1ee755 100644 --- a/extensions/browser/api/socket/tcp_socket.cc +++ b/extensions/browser/api/socket/tcp_socket.cc
@@ -128,8 +128,10 @@ accept_socket_.reset(NULL); } -int TCPSocket::Bind(const std::string& address, uint16_t port) { - return net::ERR_FAILED; +void TCPSocket::Bind(const std::string& address, + uint16_t port, + const net::CompletionCallback& callback) { + callback.Run(net::ERR_FAILED); } void TCPSocket::Read(int count, const ReadCompletionCallback& callback) {
diff --git a/extensions/browser/api/socket/tcp_socket.h b/extensions/browser/api/socket/tcp_socket.h index 02ce1c8c..bdff76ed 100644 --- a/extensions/browser/api/socket/tcp_socket.h +++ b/extensions/browser/api/socket/tcp_socket.h
@@ -34,7 +34,9 @@ void Connect(const net::AddressList& address, const CompletionCallback& callback) override; void Disconnect(bool socket_destroying) override; - int Bind(const std::string& address, uint16_t port) override; + void Bind(const std::string& address, + uint16_t port, + const CompletionCallback& callback) override; void Read(int count, const ReadCompletionCallback& callback) override; void RecvFrom(int count, const RecvFromCompletionCallback& callback) override; void SendTo(scoped_refptr<net::IOBuffer> io_buffer,
diff --git a/extensions/browser/api/socket/udp_socket.cc b/extensions/browser/api/socket/udp_socket.cc index 1ad7009b..3a55686 100644 --- a/extensions/browser/api/socket/udp_socket.cc +++ b/extensions/browser/api/socket/udp_socket.cc
@@ -30,63 +30,60 @@ return g_factory.Pointer(); } -UDPSocket::UDPSocket(const std::string& owner_extension_id) +UDPSocket::UDPSocket(network::mojom::UDPSocketPtrInfo socket, + network::mojom::UDPSocketReceiverRequest receiver_request, + const std::string& owner_extension_id) : Socket(owner_extension_id), - socket_(net::DatagramSocket::DEFAULT_BIND, - net::RandIntCallback(), - NULL, - net::NetLogSource()) {} + socket_(std::move(socket)), + socket_options_(network::mojom::UDPSocketOptions::New()), + is_bound_(false), + receiver_binding_(this) { + receiver_binding_.Bind(std::move(receiver_request)); +} UDPSocket::~UDPSocket() { Disconnect(true /* socket_destroying */); } void UDPSocket::Connect(const net::AddressList& address, - const CompletionCallback& callback) { - int result = net::ERR_CONNECTION_FAILED; - do { - if (is_connected_) - break; - - // UDP API only connects to the first address received from DNS so - // connection may not work even if other addresses are reachable. - const net::IPEndPoint& ip_end_point = address.front(); - result = socket_.Open(ip_end_point.GetFamily()); - if (result != net::OK) - break; - - result = socket_.Connect(ip_end_point); - if (result != net::OK) { - socket_.Close(); - break; - } - is_connected_ = true; - } while (false); - - callback.Run(result); + const net::CompletionCallback& callback) { + if (IsConnectedOrBound()) { + callback.Run(net::ERR_CONNECTION_FAILED); + return; + } + // UDP API only connects to the first address received from DNS so + // connection may not work even if other addresses are reachable. + const net::IPEndPoint& ip_end_point = address.front(); + socket_->Connect( + ip_end_point, std::move(socket_options_), + base::BindOnce(&UDPSocket::OnConnectCompleted, base::Unretained(this), + callback, ip_end_point)); } -int UDPSocket::Bind(const std::string& address, uint16_t port) { - if (IsBound()) - return net::ERR_CONNECTION_FAILED; +void UDPSocket::Bind(const std::string& address, + uint16_t port, + const net::CompletionCallback& callback) { + if (IsConnectedOrBound()) { + callback.Run(net::ERR_CONNECTION_FAILED); + return; + } net::IPEndPoint ip_end_point; - if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) - return net::ERR_INVALID_ARGUMENT; - - int result = socket_.Open(ip_end_point.GetFamily()); - if (result != net::OK) - return result; - - result = socket_.Bind(ip_end_point); - if (result != net::OK) - socket_.Close(); - return result; + if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) { + callback.Run(net::ERR_INVALID_ARGUMENT); + return; + } + socket_->Bind(ip_end_point, std::move(socket_options_), + base::BindOnce(&UDPSocket::OnBindCompleted, + base::Unretained(this), callback)); } void UDPSocket::Disconnect(bool socket_destroying) { is_connected_ = false; - socket_.Close(); + is_bound_ = false; + socket_->Close(); + local_addr_ = base::nullopt; + peer_addr_ = base::nullopt; read_callback_.Reset(); // TODO(devlin): Should we do this for all callbacks? if (!recv_from_callback_.is_null()) { @@ -94,7 +91,6 @@ .Run(net::ERR_CONNECTION_CLOSED, nullptr, true /* socket_destroying */, std::string(), 0); } - send_to_callback_.Reset(); multicast_groups_.clear(); } @@ -104,43 +100,40 @@ if (!read_callback_.is_null()) { callback.Run(net::ERR_IO_PENDING, nullptr, false /* socket_destroying */); return; - } else { - read_callback_ = callback; } - int result = net::ERR_FAILED; - scoped_refptr<net::IOBuffer> io_buffer; - do { - if (count < 0) { - result = net::ERR_INVALID_ARGUMENT; - break; - } + if (count < 0) { + callback.Run(net::ERR_INVALID_ARGUMENT, nullptr, + false /* socket_destroying */); + return; + } - if (!socket_.is_connected()) { - result = net::ERR_SOCKET_NOT_CONNECTED; - break; - } + if (!IsConnected()) { + callback.Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, + false /* socket_destroying */); + return; + } - io_buffer = new net::IOBuffer(count); - result = socket_.Read( - io_buffer.get(), - count, - base::Bind( - &UDPSocket::OnReadComplete, base::Unretained(this), io_buffer)); - } while (false); - - if (result != net::ERR_IO_PENDING) - OnReadComplete(io_buffer, result); + read_callback_ = callback; + socket_->ReceiveMoreWithBufferSize(1, count); + return; } int UDPSocket::WriteImpl(net::IOBuffer* io_buffer, int io_buffer_size, const net::CompletionCallback& callback) { - if (!socket_.is_connected()) + if (!IsConnected()) return net::ERR_SOCKET_NOT_CONNECTED; - else - return socket_.Write(io_buffer, io_buffer_size, callback, - Socket::GetNetworkTrafficAnnotationTag()); + base::span<const uint8_t> data( + reinterpret_cast<const uint8_t*>(io_buffer->data()), + static_cast<size_t>(io_buffer_size)); + socket_->Send( + data, + net::MutableNetworkTrafficAnnotationTag( + Socket::GetNetworkTrafficAnnotationTag()), + base::BindOnce(&UDPSocket::OnWriteOrSendToCompleted, + base::Unretained(this), callback, data.length())); + return net::ERR_IO_PENDING; } void UDPSocket::RecvFrom(int count, @@ -151,164 +144,244 @@ callback.Run(net::ERR_IO_PENDING, nullptr, false /* socket_destroying */, std::string(), 0); return; - } else { - recv_from_callback_ = callback; } - int result = net::ERR_FAILED; - scoped_refptr<net::IOBuffer> io_buffer; - scoped_refptr<IPEndPoint> address; - do { - if (count < 0) { - result = net::ERR_INVALID_ARGUMENT; - break; - } + if (count < 0) { + callback.Run(net::ERR_INVALID_ARGUMENT, nullptr, + false /* socket_destroying */, std::string(), 0); + return; + } - if (!socket_.is_connected()) { - result = net::ERR_SOCKET_NOT_CONNECTED; - break; - } + if (!is_bound_) { + callback.Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, + false /* socket_destroying */, std::string(), 0); + return; + } - io_buffer = new net::IOBuffer(count); - address = new IPEndPoint(); - result = socket_.RecvFrom(io_buffer.get(), - count, - &address->data, - base::Bind(&UDPSocket::OnRecvFromComplete, - base::Unretained(this), - io_buffer, - address)); - } while (false); - - if (result != net::ERR_IO_PENDING) - OnRecvFromComplete(io_buffer, address, result); + recv_from_callback_ = callback; + socket_->ReceiveMoreWithBufferSize(1, count); } void UDPSocket::SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, const net::IPEndPoint& address, - const CompletionCallback& callback) { + const net::CompletionCallback& callback) { DCHECK(!callback.is_null()); - if (!send_to_callback_.is_null()) { - // TODO(penghuang): Put requests in a pending queue to support multiple - // sendTo calls. - callback.Run(net::ERR_IO_PENDING); + if (!is_bound_) { + callback.Run(net::ERR_SOCKET_NOT_CONNECTED); return; - } else { - send_to_callback_ = callback; } - int result = net::ERR_FAILED; - do { - if (!socket_.is_connected()) { - result = net::ERR_SOCKET_NOT_CONNECTED; - break; - } - - result = socket_.SendTo( - io_buffer.get(), byte_count, address, - base::Bind(&UDPSocket::OnSendToComplete, base::Unretained(this))); - } while (false); - - if (result != net::ERR_IO_PENDING) - OnSendToComplete(result); + base::span<const uint8_t> data( + reinterpret_cast<const uint8_t*>(io_buffer->data()), + static_cast<size_t>(byte_count)); + socket_->SendTo( + address, data, + net::MutableNetworkTrafficAnnotationTag( + Socket::GetNetworkTrafficAnnotationTag()), + base::BindOnce(&UDPSocket::OnWriteOrSendToCompleted, + base::Unretained(this), callback, data.length())); } -bool UDPSocket::IsConnected() { return is_connected_; } +bool UDPSocket::IsConnected() { + return is_connected_; +} bool UDPSocket::GetPeerAddress(net::IPEndPoint* address) { - return !socket_.GetPeerAddress(address); + if (!IsConnected()) + return false; + if (!peer_addr_) + return false; + *address = peer_addr_.value(); + return true; } bool UDPSocket::GetLocalAddress(net::IPEndPoint* address) { - return !socket_.GetLocalAddress(address); + if (!IsConnectedOrBound()) + return false; + if (!local_addr_) + return false; + *address = local_addr_.value(); + return true; } Socket::SocketType UDPSocket::GetSocketType() const { return Socket::TYPE_UDP; } -void UDPSocket::OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, - int result) { - DCHECK(!read_callback_.is_null()); - read_callback_.Run(result, io_buffer, false /* socket_destroying */); - read_callback_.Reset(); +bool UDPSocket::IsConnectedOrBound() const { + return is_connected_ || is_bound_; } -void UDPSocket::OnRecvFromComplete(scoped_refptr<net::IOBuffer> io_buffer, - scoped_refptr<IPEndPoint> address, - int result) { - DCHECK(!recv_from_callback_.is_null()); +void UDPSocket::OnReceived(int32_t result, + const base::Optional<net::IPEndPoint>& src_addr, + base::Optional<base::span<const uint8_t>> data) { + DCHECK(!recv_from_callback_.is_null() || !read_callback_.is_null()); + std::string ip; uint16_t port = 0; - if (result > 0 && address.get()) { - IPEndPointToStringAndPort(address->data, &ip, &port); + if (result != net::OK) { + if (!read_callback_.is_null()) { + base::ResetAndReturn(&read_callback_) + .Run(result, nullptr, false /* socket_destroying */); + return; + } + base::ResetAndReturn(&recv_from_callback_) + .Run(result, nullptr, false /* socket_destroying */, ip, port); + return; } - recv_from_callback_.Run(result, io_buffer, false /* socket_destroying */, ip, - port); - recv_from_callback_.Reset(); + + scoped_refptr<net::IOBuffer> io_buffer = + new net::IOBuffer(data.value().length()); + memcpy(io_buffer->data(), data.value().data(), data.value().length()); + + if (!read_callback_.is_null()) { + base::ResetAndReturn(&read_callback_) + .Run(data.value().length(), io_buffer, false /* socket_destroying */); + return; + } + + IPEndPointToStringAndPort(src_addr.value(), &ip, &port); + base::ResetAndReturn(&recv_from_callback_) + .Run(data.value().length(), io_buffer, false /* socket_destroying */, ip, + port); } -void UDPSocket::OnSendToComplete(int result) { - DCHECK(!send_to_callback_.is_null()); - send_to_callback_.Run(result); - send_to_callback_.Reset(); +void UDPSocket::OnConnectCompleted( + const net::CompletionCallback& callback, + const net::IPEndPoint& remote_addr, + int result, + const base::Optional<net::IPEndPoint>& local_addr) { + if (result != net::OK) { + callback.Run(result); + return; + } + local_addr_ = local_addr; + peer_addr_ = remote_addr; + is_connected_ = true; + callback.Run(result); } -bool UDPSocket::IsBound() { return socket_.is_connected(); } +void UDPSocket::OnBindCompleted( + const net::CompletionCallback& callback, + int result, + const base::Optional<net::IPEndPoint>& local_addr) { + if (result != net::OK) { + callback.Run(result); + return; + } + local_addr_ = local_addr; + is_bound_ = true; + callback.Run(result); +} -int UDPSocket::JoinGroup(const std::string& address) { +void UDPSocket::OnWriteOrSendToCompleted( + const net::CompletionCallback& callback, + size_t byte_count, + int result) { + if (result == net::OK) { + callback.Run(byte_count); + return; + } + callback.Run(result); +} + +void UDPSocket::OnJoinGroupCompleted(const net::CompletionCallback& callback, + const std::string& normalized_address, + int result) { + if (result == net::OK) + multicast_groups_.push_back(normalized_address); + callback.Run(result); +} + +void UDPSocket::OnLeaveGroupCompleted( + const net::CompletionCallback& user_callback, + const std::string& normalized_address, + int result) { + if (result == net::OK) { + std::vector<std::string>::iterator find_result = std::find( + multicast_groups_.begin(), multicast_groups_.end(), normalized_address); + multicast_groups_.erase(find_result); + } + + user_callback.Run(result); +} + +void UDPSocket::JoinGroup(const std::string& address, + const net::CompletionCallback& callback) { net::IPAddress ip; - if (!ip.AssignFromIPLiteral(address)) - return net::ERR_ADDRESS_INVALID; + if (!ip.AssignFromIPLiteral(address)) { + callback.Run(net::ERR_ADDRESS_INVALID); + return; + } std::string normalized_address = ip.ToString(); - if (base::ContainsValue(multicast_groups_, normalized_address)) - return net::ERR_ADDRESS_INVALID; + if (base::ContainsValue(multicast_groups_, normalized_address)) { + callback.Run(net::ERR_ADDRESS_INVALID); + return; + } - int rv = socket_.JoinGroup(ip); - if (rv == 0) - multicast_groups_.push_back(normalized_address); - return rv; + socket_->JoinGroup( + ip, base::BindOnce(&UDPSocket::OnJoinGroupCompleted, + base::Unretained(this), callback, normalized_address)); } -int UDPSocket::LeaveGroup(const std::string& address) { +void UDPSocket::LeaveGroup(const std::string& address, + const net::CompletionCallback& callback) { net::IPAddress ip; - if (!ip.AssignFromIPLiteral(address)) - return net::ERR_ADDRESS_INVALID; + if (!ip.AssignFromIPLiteral(address)) { + callback.Run(net::ERR_ADDRESS_INVALID); + return; + } std::string normalized_address = ip.ToString(); std::vector<std::string>::iterator find_result = std::find( multicast_groups_.begin(), multicast_groups_.end(), normalized_address); - if (find_result == multicast_groups_.end()) - return net::ERR_ADDRESS_INVALID; + if (find_result == multicast_groups_.end()) { + callback.Run(net::ERR_ADDRESS_INVALID); + return; + } - int rv = socket_.LeaveGroup(ip); - if (rv == 0) - multicast_groups_.erase(find_result); - return rv; + socket_->LeaveGroup( + ip, base::BindOnce(&UDPSocket::OnLeaveGroupCompleted, + base::Unretained(this), callback, normalized_address)); } int UDPSocket::SetMulticastTimeToLive(int ttl) { - return socket_.SetMulticastTimeToLive(ttl); + if (!socket_options_) + return net::ERR_SOCKET_IS_CONNECTED; + if (ttl < 0 || ttl > 255) + return net::ERR_INVALID_ARGUMENT; + socket_options_->multicast_time_to_live = ttl; + return net::OK; } int UDPSocket::SetMulticastLoopbackMode(bool loopback) { - return socket_.SetMulticastLoopbackMode(loopback); + if (!socket_options_) + return net::ERR_SOCKET_IS_CONNECTED; + socket_options_->multicast_loopback_mode = loopback; + return net::OK; } -int UDPSocket::SetBroadcast(bool enabled) { - if (!socket_.is_connected()) { - return net::ERR_SOCKET_NOT_CONNECTED; +void UDPSocket::SetBroadcast(bool enabled, + const net::CompletionCallback& callback) { + if (!is_bound_) { + callback.Run(net::ERR_SOCKET_NOT_CONNECTED); + return; } - return socket_.SetBroadcast(enabled); + socket_->SetBroadcast(enabled, callback); } const std::vector<std::string>& UDPSocket::GetJoinedGroups() const { return multicast_groups_; } -ResumableUDPSocket::ResumableUDPSocket(const std::string& owner_extension_id) - : UDPSocket(owner_extension_id), +ResumableUDPSocket::ResumableUDPSocket( + network::mojom::UDPSocketPtrInfo socket, + network::mojom::UDPSocketReceiverRequest receiver_request, + const std::string& owner_extension_id) + : UDPSocket(std::move(socket), + std::move(receiver_request), + owner_extension_id), persistent_(false), buffer_size_(0), paused_(false) {}
diff --git a/extensions/browser/api/socket/udp_socket.h b/extensions/browser/api/socket/udp_socket.h index 22b595c..38e4e56 100644 --- a/extensions/browser/api/socket/udp_socket.h +++ b/extensions/browser/api/socket/udp_socket.h
@@ -10,42 +10,53 @@ #include <string> #include <vector> +#include "base/containers/span.h" +#include "base/optional.h" #include "extensions/browser/api/socket/socket.h" -#include "net/socket/udp_socket.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/network/public/interfaces/network_service.mojom.h" +#include "services/network/public/interfaces/udp_socket.mojom.h" namespace extensions { -class UDPSocket : public Socket { +class UDPSocket : public Socket, public network::mojom::UDPSocketReceiver { public: - explicit UDPSocket(const std::string& owner_extension_id); + UDPSocket(network::mojom::UDPSocketPtrInfo socket, + network::mojom::UDPSocketReceiverRequest receiver_request, + const std::string& owner_extension_id); ~UDPSocket() override; + // Socket implementation. void Connect(const net::AddressList& address, const CompletionCallback& callback) override; void Disconnect(bool socket_destroying) override; - int Bind(const std::string& address, uint16_t port) override; + void Bind(const std::string& address, + uint16_t port, + const CompletionCallback& callback) override; void Read(int count, const ReadCompletionCallback& callback) override; void RecvFrom(int count, const RecvFromCompletionCallback& callback) override; void SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, const net::IPEndPoint& address, const CompletionCallback& callback) override; - bool IsConnected() override; - bool GetPeerAddress(net::IPEndPoint* address) override; bool GetLocalAddress(net::IPEndPoint* address) override; Socket::SocketType GetSocketType() const override; - bool IsBound(); + // Joins a multicast group. Can only be called after a successful Bind(). + void JoinGroup(const std::string& address, + const net::CompletionCallback& callback); + // Leaves a multicast group. Can only be called after a successful Bind(). + void LeaveGroup(const std::string& address, + const net::CompletionCallback& callback); - int JoinGroup(const std::string& address); - int LeaveGroup(const std::string& address); - + // Multicast options must be set before Bind()/Connect() is called. int SetMulticastTimeToLive(int ttl); int SetMulticastLoopbackMode(bool loopback); - int SetBroadcast(bool enabled); + // Sets broadcast to |enabled|. Can only be called after a successful Bind(). + void SetBroadcast(bool enabled, const net::CompletionCallback& callback); const std::vector<std::string>& GetJoinedGroups() const; @@ -58,20 +69,42 @@ // Make net::IPEndPoint can be refcounted typedef base::RefCountedData<net::IPEndPoint> IPEndPoint; - void OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, int result); - void OnRecvFromComplete(scoped_refptr<net::IOBuffer> io_buffer, - scoped_refptr<IPEndPoint> address, - int result); - void OnSendToComplete(int result); + bool IsConnectedOrBound() const; - net::UDPSocket socket_; + // network::mojom::UDPSocketReceiver implementation. + void OnReceived(int32_t result, + const base::Optional<net::IPEndPoint>& src_addr, + base::Optional<base::span<const uint8_t>> data) override; + + void OnConnectCompleted(const net::CompletionCallback& user_callback, + const net::IPEndPoint& remote_addr, + int result, + const base::Optional<net::IPEndPoint>& local_addr); + void OnBindCompleted(const net::CompletionCallback& user_callback, + int result, + const base::Optional<net::IPEndPoint>& local_addr); + void OnWriteOrSendToCompleted(const net::CompletionCallback& user_callback, + size_t byte_count, + int result); + void OnJoinGroupCompleted(const net::CompletionCallback& user_callback, + const std::string& normalized_address, + int result); + void OnLeaveGroupCompleted(const net::CompletionCallback& user_callback, + const std::string& normalized_address, + int result); + + network::mojom::UDPSocketPtr socket_; + network::mojom::UDPSocketOptionsPtr socket_options_; + + bool is_bound_; + mojo::Binding<network::mojom::UDPSocketReceiver> receiver_binding_; + base::Optional<net::IPEndPoint> local_addr_; + base::Optional<net::IPEndPoint> peer_addr_; ReadCompletionCallback read_callback_; RecvFromCompletionCallback recv_from_callback_; - CompletionCallback send_to_callback_; - std::vector<std::string> multicast_groups_; }; @@ -80,7 +113,9 @@ // the "sockets.udp" namespace. class ResumableUDPSocket : public UDPSocket { public: - explicit ResumableUDPSocket(const std::string& owner_extension_id); + ResumableUDPSocket(network::mojom::UDPSocketPtrInfo socket, + network::mojom::UDPSocketReceiverRequest receiver_request, + const std::string& owner_extension_id); // Overriden from ApiResource bool IsPersistent() const override;
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api.cc b/extensions/browser/api/sockets_udp/sockets_udp_api.cc index 61190a325f..620b51f 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api.cc +++ b/extensions/browser/api/sockets_udp/sockets_udp_api.cc
@@ -4,6 +4,8 @@ #include "extensions/browser/api/sockets_udp/sockets_udp_api.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" #include "content/public/common/socket_permission_request.h" #include "extensions/browser/api/socket/udp_socket.h" #include "extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.h" @@ -92,11 +94,19 @@ bool SocketsUdpCreateFunction::Prepare() { params_ = sockets_udp::Create::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params_.get()); + + network::mojom::UDPSocketReceiverPtr receiver_ptr; + socket_receiver_request_ = mojo::MakeRequest(&receiver_ptr); + content::BrowserContext::GetDefaultStoragePartition(browser_context()) + ->GetNetworkContext() + ->CreateUDPSocket(mojo::MakeRequest(&socket_), std::move(receiver_ptr)); return true; } void SocketsUdpCreateFunction::Work() { - ResumableUDPSocket* socket = new ResumableUDPSocket(extension_->id()); + ResumableUDPSocket* socket = new ResumableUDPSocket( + std::move(socket_), std::move(socket_receiver_request_), + extension_->id()); sockets_udp::SocketProperties* properties = params_->properties.get(); if (properties) { @@ -156,7 +166,7 @@ if (socket->paused() != params_->paused) { socket->set_paused(params_->paused); - if (socket->IsBound() && !params_->paused) { + if (socket->IsConnected() && !params_->paused) { socket_event_dispatcher_->OnSocketResume(extension_->id(), params_->socket_id); } @@ -198,8 +208,17 @@ AsyncWorkCompleted(); return; } + socket->Bind(params_->address, params_->port, + base::BindRepeating(&SocketsUdpBindFunction::OnCompleted, this)); +} - int net_result = socket->Bind(params_->address, params_->port); +void SocketsUdpBindFunction::OnCompleted(int net_result) { + ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id); + if (!socket) { + error_ = kSocketNotFoundError; + AsyncWorkCompleted(); + return; + } results_ = sockets_udp::Bind::Results::Create(net_result); if (net_result == net::OK) { socket_event_dispatcher_->OnSocketBind(extension_->id(), @@ -261,8 +280,9 @@ return; } - socket->SendTo(io_buffer_, io_buffer_size_, addresses_.front(), - base::Bind(&SocketsUdpSendFunction::OnCompleted, this)); + socket->SendTo( + io_buffer_, io_buffer_size_, addresses_.front(), + base::BindRepeating(&SocketsUdpSendFunction::OnCompleted, this)); } void SocketsUdpSendFunction::OnCompleted(int net_result) { @@ -362,10 +382,11 @@ return true; } -void SocketsUdpJoinGroupFunction::Work() { +void SocketsUdpJoinGroupFunction::AsyncWorkStart() { ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id); if (!socket) { error_ = kSocketNotFoundError; + AsyncWorkCompleted(); return; } @@ -375,13 +396,20 @@ kWildcardPort); if (!SocketsManifestData::CheckRequest(extension(), param)) { error_ = kPermissionError; + AsyncWorkCompleted(); return; } - int net_result = socket->JoinGroup(params_->address); + socket->JoinGroup( + params_->address, + base::BindRepeating(&SocketsUdpJoinGroupFunction::OnCompleted, this)); +} + +void SocketsUdpJoinGroupFunction::OnCompleted(int net_result) { if (net_result != net::OK) error_ = net::ErrorToString(net_result); results_ = sockets_udp::JoinGroup::Results::Create(net_result); + AsyncWorkCompleted(); } SocketsUdpLeaveGroupFunction::SocketsUdpLeaveGroupFunction() {} @@ -394,10 +422,11 @@ return true; } -void SocketsUdpLeaveGroupFunction::Work() { +void SocketsUdpLeaveGroupFunction::AsyncWorkStart() { ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id); if (!socket) { error_ = kSocketNotFoundError; + AsyncWorkCompleted(); return; } @@ -407,13 +436,19 @@ kWildcardPort); if (!SocketsManifestData::CheckRequest(extension(), param)) { error_ = kPermissionError; + AsyncWorkCompleted(); return; } + socket->LeaveGroup( + params_->address, + base::BindRepeating(&SocketsUdpLeaveGroupFunction::OnCompleted, this)); +} - int net_result = socket->LeaveGroup(params_->address); - if (net_result != net::OK) - error_ = net::ErrorToString(net_result); - results_ = sockets_udp::LeaveGroup::Results::Create(net_result); +void SocketsUdpLeaveGroupFunction::OnCompleted(int result) { + if (result != net::OK) + error_ = net::ErrorToString(result); + results_ = sockets_udp::LeaveGroup::Results::Create(result); + AsyncWorkCompleted(); } SocketsUdpSetMulticastTimeToLiveFunction:: @@ -508,18 +543,24 @@ return true; } -void SocketsUdpSetBroadcastFunction::Work() { +void SocketsUdpSetBroadcastFunction::AsyncWorkStart() { ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id); if (!socket) { error_ = kSocketNotFoundError; + AsyncWorkCompleted(); return; } - int net_result = socket->SetBroadcast(params_->enabled); - if (net_result != net::OK) { + socket->SetBroadcast( + params_->enabled, + base::BindRepeating(&SocketsUdpSetBroadcastFunction::OnCompleted, this)); +} + +void SocketsUdpSetBroadcastFunction::OnCompleted(int net_result) { + if (net_result != net::OK) error_ = net::ErrorToString(net_result); - } results_ = sockets_udp::SetBroadcast::Results::Create(net_result); + AsyncWorkCompleted(); } } // namespace api
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api.h b/extensions/browser/api/sockets_udp/sockets_udp_api.h index 27ee801..ee5ddac 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api.h +++ b/extensions/browser/api/sockets_udp/sockets_udp_api.h
@@ -56,6 +56,9 @@ private: FRIEND_TEST_ALL_PREFIXES(SocketsUdpUnitTest, Create); + + network::mojom::UDPSocketPtrInfo socket_; + network::mojom::UDPSocketReceiverRequest socket_receiver_request_; std::unique_ptr<sockets_udp::Create::Params> params_; }; @@ -106,6 +109,7 @@ // AsyncApiFunction: bool Prepare() override; void AsyncWorkStart() override; + void OnCompleted(int net_result); private: std::unique_ptr<sockets_udp::Bind::Params> params_; @@ -197,9 +201,11 @@ // AsyncApiFunction bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(int result); + std::unique_ptr<sockets_udp::JoinGroup::Params> params_; }; @@ -214,9 +220,11 @@ // AsyncApiFunction bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(int result); + std::unique_ptr<sockets_udp::LeaveGroup::Params> params_; }; @@ -288,9 +296,11 @@ // AsyncApiFunction bool Prepare() override; - void Work() override; + void AsyncWorkStart() override; private: + void OnCompleted(int net_result); + std::unique_ptr<sockets_udp::SetBroadcast::Params> params_; };
diff --git a/extensions/browser/extension_navigation_ui_data.cc b/extensions/browser/extension_navigation_ui_data.cc index 1980b88..3ba2052 100644 --- a/extensions/browser/extension_navigation_ui_data.cc +++ b/extensions/browser/extension_navigation_ui_data.cc
@@ -14,25 +14,26 @@ ExtensionNavigationUIData::ExtensionNavigationUIData( content::NavigationHandle* navigation_handle, int tab_id, - int window_id) { + int window_id) + : ExtensionNavigationUIData( + navigation_handle->GetWebContents(), + tab_id, + window_id, + ExtensionApiFrameIdMap::GetFrameId(navigation_handle), + ExtensionApiFrameIdMap::GetParentFrameId(navigation_handle)) { // TODO(clamy): See if it would be possible to have just one source for the // FrameData that works both for navigations and subresources loads. - frame_data_.frame_id = ExtensionApiFrameIdMap::GetFrameId(navigation_handle); - frame_data_.parent_frame_id = - ExtensionApiFrameIdMap::GetParentFrameId(navigation_handle); - frame_data_.tab_id = tab_id; - frame_data_.window_id = window_id; +} - WebViewGuest* web_view = - WebViewGuest::FromWebContents(navigation_handle->GetWebContents()); - if (web_view) { - is_web_view_ = true; - web_view_instance_id_ = web_view->view_instance_id(); - web_view_rules_registry_id_ = web_view->rules_registry_id(); - } else { - is_web_view_ = false; - web_view_instance_id_ = web_view_rules_registry_id_ = 0; - } +// static +std::unique_ptr<ExtensionNavigationUIData> +ExtensionNavigationUIData::CreateForMainFrameNavigation( + content::WebContents* web_contents, + int tab_id, + int window_id) { + return base::WrapUnique(new ExtensionNavigationUIData( + web_contents, tab_id, window_id, ExtensionApiFrameIdMap::kTopFrameId, + ExtensionApiFrameIdMap::kInvalidFrameId)); } std::unique_ptr<ExtensionNavigationUIData> ExtensionNavigationUIData::DeepCopy() @@ -46,4 +47,26 @@ return copy; } +ExtensionNavigationUIData::ExtensionNavigationUIData( + content::WebContents* web_contents, + int tab_id, + int window_id, + int frame_id, + int parent_frame_id) { + frame_data_.window_id = window_id; + frame_data_.tab_id = tab_id; + frame_data_.frame_id = frame_id; + frame_data_.parent_frame_id = parent_frame_id; + + WebViewGuest* web_view = WebViewGuest::FromWebContents(web_contents); + if (web_view) { + is_web_view_ = true; + web_view_instance_id_ = web_view->view_instance_id(); + web_view_rules_registry_id_ = web_view->rules_registry_id(); + } else { + is_web_view_ = false; + web_view_instance_id_ = web_view_rules_registry_id_ = 0; + } +} + } // namespace extensions
diff --git a/extensions/browser/extension_navigation_ui_data.h b/extensions/browser/extension_navigation_ui_data.h index e1467e2c..ff4d214 100644 --- a/extensions/browser/extension_navigation_ui_data.h +++ b/extensions/browser/extension_navigation_ui_data.h
@@ -25,6 +25,11 @@ int tab_id, int window_id); + static std::unique_ptr<ExtensionNavigationUIData> + CreateForMainFrameNavigation(content::WebContents* web_contents, + int tab_id, + int window_id); + std::unique_ptr<ExtensionNavigationUIData> DeepCopy() const; const ExtensionApiFrameIdMap::FrameData& frame_data() const { @@ -36,6 +41,12 @@ int web_view_rules_registry_id() const { return web_view_rules_registry_id_; } private: + ExtensionNavigationUIData(content::WebContents* web_contents, + int tab_id, + int window_id, + int frame_id, + int parent_frame_id); + ExtensionApiFrameIdMap::FrameData frame_data_; bool is_web_view_; // These are only valid iff is_web_view_.
diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc index dba84a5..1578288 100644 --- a/extensions/common/url_pattern.cc +++ b/extensions/common/url_pattern.cc
@@ -487,21 +487,25 @@ bool URLPattern::ImpliesAllHosts() const { // Check if it matches all urls or is a pattern like http://*/*. - if (match_all_urls_ || - (match_subdomains_ && host_.empty() && port_ == "*" && path_ == "/*")) { + if (match_all_urls_ || (match_subdomains_ && host_.empty())) return true; - } // If this doesn't even match subdomains, it can't possibly imply all hosts. if (!match_subdomains_) return false; + // We exclude private registries because we shouldn't warn that an extension + // wants to access all hosts just for wanting to run on all e.g. appspot.com + // sites. + const net::registry_controlled_domains::PrivateRegistryFilter private_filter = + net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES; + // If there was more than just a TLD in the host (e.g., *.foobar.com), it // doesn't imply all hosts. We don't include private TLDs, so that, e.g., // *.appspot.com does not imply all hosts. if (net::registry_controlled_domains::HostHasRegistryControlledDomain( host_, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, - net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)) + private_filter)) return false; // At this point the host could either be just a TLD ("com") or some unknown @@ -513,7 +517,7 @@ return net::registry_controlled_domains::HostHasRegistryControlledDomain( "notatld." + host_, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, - net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); + private_filter); } bool URLPattern::MatchesSingleOrigin() const {
diff --git a/extensions/common/url_pattern.h b/extensions/common/url_pattern.h index efb93fa..32d9b91 100644 --- a/extensions/common/url_pattern.h +++ b/extensions/common/url_pattern.h
@@ -181,7 +181,8 @@ bool MatchesPath(base::StringPiece test) const; // Returns true if the pattern is vague enough that it implies all hosts, - // such as *://*/*. + // such as *://*/*, or if it's a common (e)TLD wildcard pattern like + // *://*.com/*. // This is an expensive method, and should be used sparingly! // You should probably use URLPatternSet::ShouldWarnAllHosts(), which is // cached.
diff --git a/extensions/common/url_pattern_unittest.cc b/extensions/common/url_pattern_unittest.cc index f504a8d8..ef85fca 100644 --- a/extensions/common/url_pattern_unittest.cc +++ b/extensions/common/url_pattern_unittest.cc
@@ -929,4 +929,46 @@ EXPECT_TRUE(trailing_pattern.MatchesURL(trailing_dot_domain)); } +TEST(ExtensionURLPatternTest, ImpliesAllHosts) { + constexpr struct { + const char* pattern; + bool implies_all_hosts; + } tests[] = { + // <all_urls> obviously implies all hosts. + {"*://*/*", true}, + {"<all_urls>", true}, + + // Matching a single scheme effectively all hosts. + {"http://*/*", true}, + {"https://*/*", true}, + + // Specifying a path under any origin is effectively all hosts. + {"*://*/maps", true}, + + // Matching a given (e)TLD is effectively all hosts. + {"https://*.com/*", true}, + {"*://*.co.uk/*", true}, + + // Matching an arbitrary domain with a given path or port is effectively + // all hosts. + {"*://*.com/maps", true}, + {"http://*.com:80/*", true}, + + // We don't include private registries (like appspot.com) as implying + // all hosts - there's legitimate reasons to want to always run on + // *.appspot.com, and we shouldn't say that it's close enough to every + // site. + {"*://*.appspot.com/*", false}, + + // All example.com sites is clearly not all hosts. + {"*://*.example.com/*", false}, + }; + + for (const auto& test : tests) { + const URLPattern pattern(URLPattern::SCHEME_ALL, test.pattern); + EXPECT_EQ(test.implies_all_hosts, pattern.ImpliesAllHosts()) + << test.pattern; + } +} + } // namespace
diff --git a/ios/DEPS b/ios/DEPS index 0644d46..0c9ccaf 100644 --- a/ios/DEPS +++ b/ios/DEPS
@@ -17,3 +17,9 @@ # to crbug.com/708307. "-ios/web/public/test/http_server/http_server.h", ] + +specific_include_rules = { + ".*test\.mm": [ + "+services/network/public/cpp", + ], +}
diff --git a/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer.h b/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer.h index 58500b8d..8aa965dd 100644 --- a/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer.h +++ b/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer.h
@@ -18,6 +18,18 @@ #pragma mark - Scrolling events +// Observer method for objects that care about the size of the scroll view +// displaying the main content. +- (void)broadcastScrollViewSize:(CGSize)scrollViewSize; + +// Observer method for objects that care about the height of the current page's +// rendered contents. +- (void)broadcastScrollViewContentSize:(CGSize)contentSize; + +// Observer method for objects that care about the content inset for the scroll +// view displaying the main content area. +- (void)broadcastScrollViewContentInset:(UIEdgeInsets)contentInset; + // Observer method for objects that care about the current vertical (y-axis) // scroll offset of the tab content area. - (void)broadcastContentScrollOffset:(CGFloat)offset; @@ -27,6 +39,10 @@ - (void)broadcastScrollViewIsScrolling:(BOOL)scrolling; // Observer method for objects that care about whether the main content area is +// zooming. +- (void)broadcastScrollViewIsZooming:(BOOL)zooming; + +// Observer method for objects that care about whether the main content area is // being dragged. Note that if a drag ends with residual velocity, it's // possible for |dragging| to be NO while |scrolling| is still YES. - (void)broadcastScrollViewIsDragging:(BOOL)dragging;
diff --git a/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer_bridge.h b/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer_bridge.h index 5db36bd..fa7b64c 100644 --- a/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer_bridge.h +++ b/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer_bridge.h
@@ -12,12 +12,24 @@ public: virtual ~ChromeBroadcastObserverInterface(); + // Invoked by |-broadcastScrollViewSize:|. + virtual void OnScrollViewSizeBroadcasted(CGSize scroll_view_size) {} + + // Invoked by |-broadcastScrollViewContentSize:|. + virtual void OnScrollViewContentSizeBroadcasted(CGSize content_size) {} + + // Invoked by |-broadcastScrollViewContentInset:|. + virtual void OnScrollViewContentInsetBroadcasted(UIEdgeInsets conent_inset) {} + // Invoked by |-broadcastContentScrollOffset:|. virtual void OnContentScrollOffsetBroadcasted(CGFloat offset) {} // Invoked by |-broadcastScrollViewIsScrolling:|. virtual void OnScrollViewIsScrollingBroadcasted(bool scrolling) {} + // Invoked by |-broadcastScrollViewIsZooming:|. + virtual void OnScrollViewIsZoomingBroadcasted(bool zooming) {} + // Invoked by |-broadcastScrollViewIsDragging:|. virtual void OnScrollViewIsDraggingBroadcasted(bool dragging) {}
diff --git a/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer_bridge.mm b/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer_bridge.mm index 6c4e3da..7eede52 100644 --- a/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer_bridge.mm +++ b/ios/chrome/browser/ui/broadcaster/chrome_broadcast_observer_bridge.mm
@@ -23,6 +23,18 @@ return self; } +- (void)broadcastScrollViewSize:(CGSize)scrollViewSize { + self.observer->OnScrollViewSizeBroadcasted(scrollViewSize); +} + +- (void)broadcastScrollViewContentSize:(CGSize)contentSize { + self.observer->OnScrollViewContentSizeBroadcasted(contentSize); +} + +- (void)broadcastScrollViewContentInset:(UIEdgeInsets)contentInset { + self.observer->OnScrollViewContentInsetBroadcasted(contentInset); +} + - (void)broadcastContentScrollOffset:(CGFloat)offset { self.observer->OnContentScrollOffsetBroadcasted(offset); } @@ -31,6 +43,10 @@ self.observer->OnScrollViewIsScrollingBroadcasted(scrolling); } +- (void)broadcastScrollViewIsZooming:(BOOL)zooming { + self.observer->OnScrollViewIsZoomingBroadcasted(zooming); +} + - (void)broadcastScrollViewIsDragging:(BOOL)dragging { self.observer->OnScrollViewIsDraggingBroadcasted(dragging); }
diff --git a/ios/chrome/browser/ui/broadcaster/chrome_broadcaster.mm b/ios/chrome/browser/ui/broadcaster/chrome_broadcaster.mm index 4b3606b..c4f077c 100644 --- a/ios/chrome/browser/ui/broadcaster/chrome_broadcaster.mm +++ b/ios/chrome/browser/ui/broadcaster/chrome_broadcaster.mm
@@ -317,6 +317,12 @@ } else if (type == @encode(CGRect)) { CGRect rectValue = value.CGRectValue; [invocation setArgument:&rectValue atIndex:2]; + } else if (type == @encode(CGSize)) { + CGSize sizeValue = value.CGSizeValue; + [invocation setArgument:&sizeValue atIndex:2]; + } else if (type == @encode(UIEdgeInsets)) { + UIEdgeInsets insetValue = value.UIEdgeInsetsValue; + [invocation setArgument:&insetValue atIndex:2]; } else if (type == @encode(int)) { DCHECK(valueAsNumber); int intValue = valueAsNumber.intValue;
diff --git a/ios/chrome/browser/ui/broadcaster/chrome_broadcaster_unittest.mm b/ios/chrome/browser/ui/broadcaster/chrome_broadcaster_unittest.mm index 76e216e..42d999f 100644 --- a/ios/chrome/browser/ui/broadcaster/chrome_broadcaster_unittest.mm +++ b/ios/chrome/browser/ui/broadcaster/chrome_broadcaster_unittest.mm
@@ -17,15 +17,25 @@ @interface TestObserver : NSObject<ChromeBroadcastObserver> @property(nonatomic) BOOL lastObservedBool; @property(nonatomic) CGFloat lastObservedCGFloat; +@property(nonatomic) CGSize lastObservedCGSize; +@property(nonatomic) UIEdgeInsets lastObservedUIEdgeInsets; @property(nonatomic) NSInteger tabStripVisibleCallCount; @property(nonatomic) NSInteger contentScrollOffsetCallCount; +@property(nonatomic) NSInteger scrollViewSizeCallCount; +@property(nonatomic) NSInteger contentSizeCallCount; +@property(nonatomic) NSInteger contentInsetCallCount; @end @implementation TestObserver @synthesize lastObservedBool = _lastObservedBool; @synthesize lastObservedCGFloat = _lastObservedCGFloat; +@synthesize lastObservedCGSize = _lastObservedCGSize; +@synthesize lastObservedUIEdgeInsets = _lastObservedUIEdgeInsets; @synthesize tabStripVisibleCallCount = _tabStripVisibleCallCount; @synthesize contentScrollOffsetCallCount = _contentScrollOffsetCallCount; +@synthesize scrollViewSizeCallCount = _scrollViewSizeCallCount; +@synthesize contentSizeCallCount = _contentSizeCallCount; +@synthesize contentInsetCallCount = _contentInsetCallCount; - (void)broadcastScrollViewIsScrolling:(BOOL)visible { self.tabStripVisibleCallCount++; @@ -37,15 +47,34 @@ self.lastObservedCGFloat = offset; } +- (void)broadcastScrollViewSize:(CGSize)scrollViewSize { + self.scrollViewSizeCallCount++; + self.lastObservedCGSize = scrollViewSize; +} + +- (void)broadcastScrollViewContentSize:(CGSize)contentSize { + self.contentSizeCallCount++; + self.lastObservedCGSize = contentSize; +} + +- (void)broadcastScrollViewContentInset:(UIEdgeInsets)contentInset { + self.contentInsetCallCount++; + self.lastObservedUIEdgeInsets = contentInset; +} + @end @interface TestObservable : NSObject @property(nonatomic) BOOL observableBool; @property(nonatomic) CGFloat observableCGFloat; +@property(nonatomic) CGSize observableCGSize; +@property(nonatomic) UIEdgeInsets observableUIEdgeInsets; @end @implementation TestObservable @synthesize observableBool = _observableBool; @synthesize observableCGFloat = _observableCGFloat; +@synthesize observableCGSize = _observableCGSize; +@synthesize observableUIEdgeInsets = _observableUIEdgeInsets; @end typedef PlatformTest ChromeBroadcasterTest; @@ -147,6 +176,97 @@ EXPECT_EQ(2, observer.contentScrollOffsetCallCount); } +TEST_F(ChromeBroadcasterTest, TestObserveScrollViewSizeFirst) { + ChromeBroadcaster* broadcaster = [[ChromeBroadcaster alloc] init]; + TestObserver* observer = [[TestObserver alloc] init]; + EXPECT_TRUE(CGSizeEqualToSize(observer.lastObservedCGSize, CGSizeZero)); + EXPECT_EQ(0, observer.scrollViewSizeCallCount); + [broadcaster addObserver:observer + forSelector:@selector(broadcastScrollViewSize:)]; + EXPECT_TRUE(CGSizeEqualToSize(observer.lastObservedCGSize, CGSizeZero)); + EXPECT_EQ(0, observer.scrollViewSizeCallCount); + + TestObservable* observable = [[TestObservable alloc] init]; + CGSize kScrollViewSize1 = CGSizeMake(100, 100); + observable.observableCGSize = kScrollViewSize1; + EXPECT_TRUE(CGSizeEqualToSize(observer.lastObservedCGSize, CGSizeZero)); + EXPECT_EQ(0, observer.scrollViewSizeCallCount); + + [broadcaster broadcastValue:@"observableCGSize" + ofObject:observable + selector:@selector(broadcastScrollViewSize:)]; + EXPECT_TRUE(CGSizeEqualToSize(observer.lastObservedCGSize, kScrollViewSize1)); + EXPECT_EQ(1, observer.scrollViewSizeCallCount); + + CGSize kScrollViewSize2 = CGSizeMake(200, 200); + observable.observableCGSize = kScrollViewSize2; + EXPECT_TRUE(CGSizeEqualToSize(observer.lastObservedCGSize, kScrollViewSize2)); + EXPECT_EQ(2, observer.scrollViewSizeCallCount); +} + +TEST_F(ChromeBroadcasterTest, TestObserveContentSizeFirst) { + ChromeBroadcaster* broadcaster = [[ChromeBroadcaster alloc] init]; + TestObserver* observer = [[TestObserver alloc] init]; + EXPECT_TRUE(CGSizeEqualToSize(observer.lastObservedCGSize, CGSizeZero)); + EXPECT_EQ(0, observer.contentSizeCallCount); + [broadcaster addObserver:observer + forSelector:@selector(broadcastScrollViewContentSize:)]; + EXPECT_TRUE(CGSizeEqualToSize(observer.lastObservedCGSize, CGSizeZero)); + EXPECT_EQ(0, observer.contentSizeCallCount); + + TestObservable* observable = [[TestObservable alloc] init]; + CGSize kContentViewSize1 = CGSizeMake(100, 100); + observable.observableCGSize = kContentViewSize1; + EXPECT_TRUE(CGSizeEqualToSize(observer.lastObservedCGSize, CGSizeZero)); + EXPECT_EQ(0, observer.contentSizeCallCount); + + [broadcaster broadcastValue:@"observableCGSize" + ofObject:observable + selector:@selector(broadcastScrollViewContentSize:)]; + EXPECT_TRUE( + CGSizeEqualToSize(observer.lastObservedCGSize, kContentViewSize1)); + EXPECT_EQ(1, observer.contentSizeCallCount); + + CGSize kContentViewSize2 = CGSizeMake(200, 200); + observable.observableCGSize = kContentViewSize2; + EXPECT_TRUE( + CGSizeEqualToSize(observer.lastObservedCGSize, kContentViewSize2)); + EXPECT_EQ(2, observer.contentSizeCallCount); +} + +TEST_F(ChromeBroadcasterTest, TestObserveContentInsetFirst) { + ChromeBroadcaster* broadcaster = [[ChromeBroadcaster alloc] init]; + TestObserver* observer = [[TestObserver alloc] init]; + EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(observer.lastObservedUIEdgeInsets, + UIEdgeInsetsZero)); + EXPECT_EQ(0, observer.contentInsetCallCount); + [broadcaster addObserver:observer + forSelector:@selector(broadcastScrollViewContentInset:)]; + EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(observer.lastObservedUIEdgeInsets, + UIEdgeInsetsZero)); + EXPECT_EQ(0, observer.contentInsetCallCount); + + TestObservable* observable = [[TestObservable alloc] init]; + UIEdgeInsets kInsets1 = UIEdgeInsetsMake(1, 1, 1, 1); + observable.observableUIEdgeInsets = kInsets1; + EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(observer.lastObservedUIEdgeInsets, + UIEdgeInsetsZero)); + EXPECT_EQ(0, observer.contentInsetCallCount); + + [broadcaster broadcastValue:@"observableUIEdgeInsets" + ofObject:observable + selector:@selector(broadcastScrollViewContentInset:)]; + EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(observer.lastObservedUIEdgeInsets, + kInsets1)); + EXPECT_EQ(1, observer.contentInsetCallCount); + + UIEdgeInsets kInsets2 = UIEdgeInsetsMake(2, 2, 2, 2); + observable.observableUIEdgeInsets = kInsets2; + EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(observer.lastObservedUIEdgeInsets, + kInsets2)); + EXPECT_EQ(2, observer.contentInsetCallCount); +} + TEST_F(ChromeBroadcasterTest, TestBroadcastManyFloats) { ChromeBroadcaster* broadcaster = [[ChromeBroadcaster alloc] init]; NSMutableArray<TestObserver*>* observers = [[NSMutableArray alloc] init];
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.mm index b169878..a1a6403 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.mm
@@ -27,10 +27,18 @@ mediator:mediator_.get()]) { DCHECK(broadcaster_); [broadcaster_ addObserver:bridge_ + forSelector:@selector(broadcastScrollViewSize:)]; + [broadcaster_ addObserver:bridge_ + forSelector:@selector(broadcastScrollViewContentSize:)]; + [broadcaster_ addObserver:bridge_ + forSelector:@selector(broadcastScrollViewContentInset:)]; + [broadcaster_ addObserver:bridge_ forSelector:@selector(broadcastContentScrollOffset:)]; [broadcaster_ addObserver:bridge_ forSelector:@selector(broadcastScrollViewIsScrolling:)]; [broadcaster_ addObserver:bridge_ + forSelector:@selector(broadcastScrollViewIsZooming:)]; + [broadcaster_ addObserver:bridge_ forSelector:@selector(broadcastScrollViewIsDragging:)]; [broadcaster_ addObserver:bridge_ forSelector:@selector(broadcastToolbarHeight:)]; @@ -81,10 +89,18 @@ if (web_state_list_observer_) web_state_list_observer_->Disconnect(); [broadcaster_ removeObserver:bridge_ + forSelector:@selector(broadcastScrollViewSize:)]; + [broadcaster_ removeObserver:bridge_ + forSelector:@selector(broadcastScrollViewContentSize:)]; + [broadcaster_ removeObserver:bridge_ + forSelector:@selector(broadcastScrollViewContentInset:)]; + [broadcaster_ removeObserver:bridge_ forSelector:@selector(broadcastContentScrollOffset:)]; [broadcaster_ removeObserver:bridge_ forSelector:@selector(broadcastScrollViewIsScrolling:)]; [broadcaster_ removeObserver:bridge_ + forSelector:@selector(broadcastScrollViewIsZooming:)]; + [broadcaster_ removeObserver:bridge_ forSelector:@selector(broadcastScrollViewIsDragging:)]; [broadcaster_ removeObserver:bridge_ forSelector:@selector(broadcastToolbarHeight:)];
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model.h b/ios/chrome/browser/ui/fullscreen/fullscreen_model.h index 46ac581..fb7b9f3 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_model.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model.h
@@ -39,6 +39,9 @@ // by navigations or toolbar height changes. bool has_base_offset() const { return !std::isnan(base_offset_); } + // The base offset against which the fullscreen progress is being calculated. + CGFloat base_offset() const { return base_offset_; } + // Increments and decrements |disabled_counter_| for features that require the // toolbar be completely visible. void IncrementDisabledCounter(); @@ -56,6 +59,19 @@ void SetToolbarHeight(CGFloat toolbar_height); CGFloat GetToolbarHeight() const; + // Setter for the height of the scroll view displaying the main content. + void SetScrollViewHeight(CGFloat scroll_view_height); + CGFloat GetScrollViewHeight() const; + + // Setter for the current height of the rendered page. + void SetContentHeight(CGFloat content_height); + CGFloat GetContentHeight() const; + + // Setter for the top content inset of the scroll view displaying the main + // content. + void SetTopContentInset(CGFloat top_inset); + CGFloat GetTopContentInset() const; + // Setter for the current vertical content offset. Setting this will // recalculate the progress value. void SetYContentOffset(CGFloat y_content_offset); @@ -65,24 +81,46 @@ // and the progress value is not 0.0 or 1.0, the model will round to the // nearest value. void SetScrollViewIsScrolling(bool scrolling); - bool ISScrollViewScrolling() const; + bool IsScrollViewScrolling() const; + + // Setter for whether the scroll view is zooming. + void SetScrollViewIsZooming(bool zooming); + bool IsScrollViewZooming() const; // Setter for whether the scroll view is being dragged. void SetScrollViewIsDragging(bool dragging); bool IsScrollViewDragging() const; private: - // Setter for |progress_|. Notifies observers of the new value if - // |notify_observers| is true. - void SetProgress(CGFloat progress); + // Returns how a scroll to the current |y_content_offset_| from |from_offset| + // should be handled. + enum class ScrollAction : short { + kIgnore, // Ignore the scroll. + kUpdateBaseOffset, // Update |base_offset_| only. + kUpdateProgress, // Update |progress_| only. + kUpdateBaseOffsetAndProgress, // Update |bse_offset_| and |progress_|. + }; + ScrollAction ActionForScrollFromOffset(CGFloat from_offset) const; // Updates the base offset given the current y content offset, progress, and // toolbar height. void UpdateBaseOffset(); + // Updates the progress value given the current y content offset, base offset, + // and toolbar height. + void UpdateProgress(); + + // Setter for |progress_|. Notifies observers of the new value if + // |notify_observers| is true. + void SetProgress(CGFloat progress); + // ChromeBroadcastObserverInterface: + void OnScrollViewSizeBroadcasted(CGSize scroll_view_size) override; + void OnScrollViewContentSizeBroadcasted(CGSize content_size) override; + void OnScrollViewContentInsetBroadcasted(UIEdgeInsets content_inset) override; void OnContentScrollOffsetBroadcasted(CGFloat offset) override; void OnScrollViewIsScrollingBroadcasted(bool scrolling) override; + void OnScrollViewIsZoomingBroadcasted(bool zooming) override; void OnScrollViewIsDraggingBroadcasted(bool dragging) override; void OnToolbarHeightBroadcasted(CGFloat toolbar_height) override; @@ -98,10 +136,18 @@ CGFloat toolbar_height_ = 0.0; // The current vertical content offset of the main content. CGFloat y_content_offset_ = 0.0; + // The height of the scroll view displaying the current page. + CGFloat scroll_view_height_ = 0.0; + // The height of the current page's rendered content. + CGFloat content_height_ = 0.0; + // The top inset of the scroll view displaying the current page. + CGFloat top_inset_ = 0.0; // How many currently-running features require the toolbar be visible. size_t disabled_counter_ = 0; // Whether the main content is being scrolled. bool scrolling_ = false; + // Whether the scroll view is zooming. + bool zooming_ = false; // Whether the main content is being dragged. bool dragging_ = false; // The number of FullscreenModelObserver callbacks currently being executed.
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm index 93521e64..3d261b66 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm
@@ -40,7 +40,7 @@ // Fullscreen observers are expected to show the toolbar when fullscreen is // disabled. Update the internal state to match this. SetProgress(1.0); - base_offset_ = NAN; + UpdateBaseOffset(); } } @@ -84,21 +84,47 @@ return toolbar_height_; } +void FullscreenModel::SetScrollViewHeight(CGFloat scroll_view_height) { + scroll_view_height_ = scroll_view_height; +} + +CGFloat FullscreenModel::GetScrollViewHeight() const { + return scroll_view_height_; +} + +void FullscreenModel::SetContentHeight(CGFloat content_height) { + content_height_ = content_height; +} + +CGFloat FullscreenModel::GetContentHeight() const { + return content_height_; +} + +void FullscreenModel::SetTopContentInset(CGFloat top_inset) { + top_inset_ = top_inset; +} + +CGFloat FullscreenModel::GetTopContentInset() const { + return top_inset_; +} + void FullscreenModel::SetYContentOffset(CGFloat y_content_offset) { - + CGFloat from_offset = y_content_offset_; y_content_offset_ = y_content_offset; - - if (!has_base_offset()) - UpdateBaseOffset(); - - if (!enabled()) - return; - - if (scrolling_ && !observer_callback_count_) { - CGFloat delta = base_offset_ - y_content_offset_; - SetProgress(1.0 + delta / toolbar_height_); - } else { - UpdateBaseOffset(); + switch (ActionForScrollFromOffset(from_offset)) { + case ScrollAction::kUpdateBaseOffset: + UpdateBaseOffset(); + break; + case ScrollAction::kUpdateProgress: + UpdateProgress(); + break; + case ScrollAction::kUpdateBaseOffsetAndProgress: + UpdateBaseOffset(); + UpdateProgress(); + break; + case ScrollAction::kIgnore: + // no op. + break; } } @@ -118,10 +144,18 @@ } } -bool FullscreenModel::ISScrollViewScrolling() const { +bool FullscreenModel::IsScrollViewScrolling() const { return scrolling_; } +void FullscreenModel::SetScrollViewIsZooming(bool zooming) { + zooming_ = zooming; +} + +bool FullscreenModel::IsScrollViewZooming() const { + return zooming_; +} + void FullscreenModel::SetScrollViewIsDragging(bool dragging) { if (dragging_ == dragging) return; @@ -139,6 +173,51 @@ return dragging_; } +FullscreenModel::ScrollAction FullscreenModel::ActionForScrollFromOffset( + CGFloat from_offset) const { + // Update the base offset but don't recalculate progress if: + // - the model is disabled, + // - the scroll is not triggered by a user action, + // - the sroll view is zooming, + // - the scroll is triggered from a FullscreenModelObserver callback, + // - there is no toolbar, + // - the scroll offset doesn't change. + if (!enabled() || !scrolling_ || zooming_ || observer_callback_count_ || + AreCGFloatsEqual(toolbar_height_, 0.0) || + AreCGFloatsEqual(y_content_offset_, from_offset)) { + return ScrollAction::kUpdateBaseOffset; + } + + // Ignore if: + // - the scroll is a bounce-up animation at the top, + // - the scroll is a bounce-down animation at the bottom, + // - the scroll is attempting to scroll content up when it already fits. + bool scrolling_content_down = y_content_offset_ - from_offset < 0.0; + bool scrolling_past_top = y_content_offset_ <= -top_inset_; + bool scrolling_past_bottom = + y_content_offset_ + scroll_view_height_ >= content_height_; + bool content_fits = content_height_ <= scroll_view_height_ - top_inset_; + if ((scrolling_past_top && !scrolling_content_down) || + (scrolling_past_bottom && scrolling_content_down) || + (content_fits && !scrolling_content_down)) { + return ScrollAction::kIgnore; + } + + // All other scrolls should result in an updated progress value. If the model + // doesn't have a base offset, it should also be updated. + return has_base_offset() ? ScrollAction::kUpdateProgress + : ScrollAction::kUpdateBaseOffsetAndProgress; +} + +void FullscreenModel::UpdateProgress() { + CGFloat delta = base_offset_ - y_content_offset_; + SetProgress(1.0 + delta / toolbar_height_); +} + +void FullscreenModel::UpdateBaseOffset() { + base_offset_ = y_content_offset_ - (1.0 - progress_) * toolbar_height_; +} + void FullscreenModel::SetProgress(CGFloat progress) { progress = std::min(static_cast<CGFloat>(1.0), progress); progress = std::max(static_cast<CGFloat>(0.0), progress); @@ -152,8 +231,17 @@ } } -void FullscreenModel::UpdateBaseOffset() { - base_offset_ = y_content_offset_ - (1.0 - progress_) * toolbar_height_; +void FullscreenModel::OnScrollViewSizeBroadcasted(CGSize scroll_view_size) { + SetScrollViewHeight(scroll_view_size.height); +} + +void FullscreenModel::OnScrollViewContentSizeBroadcasted(CGSize content_size) { + SetContentHeight(content_size.height); +} + +void FullscreenModel::OnScrollViewContentInsetBroadcasted( + UIEdgeInsets content_inset) { + SetTopContentInset(content_inset.top); } void FullscreenModel::OnContentScrollOffsetBroadcasted(CGFloat offset) { @@ -164,6 +252,10 @@ SetScrollViewIsScrolling(scrolling); } +void FullscreenModel::OnScrollViewIsZoomingBroadcasted(bool zooming) { + SetScrollViewIsZooming(zooming); +} + void FullscreenModel::OnScrollViewIsDraggingBroadcasted(bool dragging) { SetScrollViewIsDragging(dragging); }
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model_unittest.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_model_unittest.mm index 949921fc..fff3815 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_model_unittest.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model_unittest.mm
@@ -16,6 +16,10 @@ namespace { // The toolbar height to use for tests. const CGFloat kToolbarHeight = 50.0; +// The scroll view height used for tests. +const CGFloat kScrollViewHeight = 400.0; +// The content height used for tests. +const CGFloat kContentHeight = 5000.0; } // namespace // Test fixture for FullscreenModel. @@ -26,6 +30,8 @@ // Set the toolbar height to kToolbarHeight, and simulate a page load that // finishes with a 0.0 y content offset. model_.SetToolbarHeight(kToolbarHeight); + model_.SetScrollViewHeight(kScrollViewHeight); + model_.SetContentHeight(kContentHeight); model_.ResetForNavigation(); model_.SetYContentOffset(0.0); } @@ -56,7 +62,8 @@ // Since the model has been disabled the Toolbar is shown, verify that the // model state reflects that. EXPECT_EQ(observer().progress(), 1.0); - EXPECT_FALSE(model().has_base_offset()); + EXPECT_EQ(model().base_offset(), + GetFullscreenBaseOffsetForProgress(&model(), 1.0)); // Increment again and check that the model is still disabled. model().IncrementDisabledCounter(); EXPECT_FALSE(model().enabled()); @@ -129,15 +136,47 @@ EXPECT_EQ(model().GetYContentOffset(), kFinalProgress * kToolbarHeight); } +// Tests that updating the y content offset of a disabled model only updates its +// base offset. +TEST_F(FullscreenModelTest, DisabledScroll) { + const CGFloat kProgress = 0.5; + model().IncrementDisabledCounter(); + SimulateFullscreenUserScrollForProgress(&model(), kProgress); + EXPECT_EQ(observer().progress(), 1.0); + EXPECT_EQ(model().base_offset(), + GetFullscreenBaseOffsetForProgress(&model(), 1.0)); +} + // Tests that updating the y content offset programmatically (i.e. while the -// scroll view is not scrolling) does not produce a new progress value for -// observers. +// scroll view is not scrolling) only updates the base offset. TEST_F(FullscreenModelTest, ProgrammaticScroll) { // Perform a programmatic scroll that would result in a progress of 0.5, and // verify that the initial progress value of 1.0 is maintained. const CGFloat kProgress = 0.5; model().SetYContentOffset(kProgress * kToolbarHeight); EXPECT_EQ(observer().progress(), 1.0); + EXPECT_EQ(model().base_offset(), + GetFullscreenBaseOffsetForProgress(&model(), 1.0)); +} + +// Tests that updating the y content offset while zooming only updates the +// model's base offset. +TEST_F(FullscreenModelTest, ZoomScroll) { + const CGFloat kProgress = 0.5; + model().SetScrollViewIsZooming(true); + SimulateFullscreenUserScrollForProgress(&model(), kProgress); + EXPECT_EQ(observer().progress(), 1.0); + EXPECT_EQ(model().base_offset(), + GetFullscreenBaseOffsetForProgress(&model(), 1.0)); +} + +// Tests that updating the y content offset while the toolbar height is 0 only +// updates the model's base offset. +TEST_F(FullscreenModelTest, NoToolbarScroll) { + model().SetToolbarHeight(0.0); + model().SetYContentOffset(100); + EXPECT_EQ(observer().progress(), 1.0); + EXPECT_EQ(model().base_offset(), 100); } // Tests that setting scrolling to false sends a scroll end signal to its
diff --git a/ios/chrome/browser/ui/fullscreen/test/fullscreen_model_test_util.mm b/ios/chrome/browser/ui/fullscreen/test/fullscreen_model_test_util.mm index b00ff8c2..997bacb 100644 --- a/ios/chrome/browser/ui/fullscreen/test/fullscreen_model_test_util.mm +++ b/ios/chrome/browser/ui/fullscreen/test/fullscreen_model_test_util.mm
@@ -15,6 +15,8 @@ CGFloat toolbar_height) { EXPECT_GE(toolbar_height, 0.0); model->SetToolbarHeight(toolbar_height); + model->SetScrollViewHeight(2 * toolbar_height); + model->SetContentHeight(2 * model->GetScrollViewHeight()); model->ResetForNavigation(); model->SetYContentOffset(0.0); }
diff --git a/ios/chrome/browser/ui/main_content/main_content_ui_broadcasting_util.mm b/ios/chrome/browser/ui/main_content/main_content_ui_broadcasting_util.mm index 224e464e..e4d8e5d 100644 --- a/ios/chrome/browser/ui/main_content/main_content_ui_broadcasting_util.mm +++ b/ios/chrome/browser/ui/main_content/main_content_ui_broadcasting_util.mm
@@ -14,22 +14,41 @@ void StartBroadcastingMainContentUI(id<MainContentUI> main_content, ChromeBroadcaster* broadcaster) { + [broadcaster broadcastValue:@"scrollViewSize" + ofObject:main_content.mainContentUIState + selector:@selector(broadcastScrollViewSize:)]; + [broadcaster broadcastValue:@"contentSize" + ofObject:main_content.mainContentUIState + selector:@selector(broadcastScrollViewContentSize:)]; + [broadcaster broadcastValue:@"contentInset" + ofObject:main_content.mainContentUIState + selector:@selector(broadcastScrollViewContentInset:)]; [broadcaster broadcastValue:@"yContentOffset" ofObject:main_content.mainContentUIState selector:@selector(broadcastContentScrollOffset:)]; [broadcaster broadcastValue:@"scrolling" ofObject:main_content.mainContentUIState selector:@selector(broadcastScrollViewIsScrolling:)]; + [broadcaster broadcastValue:@"zooming" + ofObject:main_content.mainContentUIState + selector:@selector(broadcastScrollViewIsZooming:)]; [broadcaster broadcastValue:@"dragging" ofObject:main_content.mainContentUIState selector:@selector(broadcastScrollViewIsDragging:)]; } void StopBroadcastingMainContentUI(ChromeBroadcaster* broadcaster) { + [broadcaster stopBroadcastingForSelector:@selector(broadcastScrollViewSize:)]; + [broadcaster + stopBroadcastingForSelector:@selector(broadcastScrollViewContentSize:)]; + [broadcaster + stopBroadcastingForSelector:@selector(broadcastScrollViewContentInset:)]; [broadcaster stopBroadcastingForSelector:@selector(broadcastContentScrollOffset:)]; [broadcaster stopBroadcastingForSelector:@selector(broadcastScrollViewIsScrolling:)]; [broadcaster + stopBroadcastingForSelector:@selector(broadcastScrollViewIsZooming:)]; + [broadcaster stopBroadcastingForSelector:@selector(broadcastScrollViewIsDragging:)]; }
diff --git a/ios/chrome/browser/ui/main_content/main_content_ui_state.h b/ios/chrome/browser/ui/main_content/main_content_ui_state.h index f789265..22f4f0b 100644 --- a/ios/chrome/browser/ui/main_content/main_content_ui_state.h +++ b/ios/chrome/browser/ui/main_content/main_content_ui_state.h
@@ -10,12 +10,24 @@ // An object encapsulating the broadcasted state of the main scrollable content. @interface MainContentUIState : NSObject +// The size of the scroll view displaying the main content. +// This should be broadcast using |-broadcastScrollViewSize:|. +@property(nonatomic, readonly) CGSize scrollViewSize; +// The height of the current page's rendered content. +// This should be broadcast using |-broadcastScrollViewContentSize:|. +@property(nonatomic, readonly) CGSize contentSize; +// The content inset of the scroll view displaying the main content. +// This should be broadcast using |-broadcastScrollViewContentInset:|. +@property(nonatomic, readonly) UIEdgeInsets contentInset; // The vertical offset of the main content. // This should be broadcast using |-broadcastContentScrollOffset:|. @property(nonatomic, readonly) CGFloat yContentOffset; // Whether the scroll view is currently scrolling. // This should be broadcast using |-broadcastScrollViewIsScrolling:|. @property(nonatomic, readonly, getter=isScrolling) BOOL scrolling; +// Whether the scroll view is currently zooming. +// This should be broadcast using |-broadcastScrollViewIsZooming:|. +@property(nonatomic, readonly, getter=isZooming) BOOL zooming; // Whether the scroll view is currently being dragged. // This should be broadcast using |-broadcastScrollViewIsDragging:|. @property(nonatomic, readonly, getter=isDragging) BOOL dragging; @@ -33,6 +45,12 @@ NS_DESIGNATED_INITIALIZER; - (nullable instancetype)init NS_UNAVAILABLE; +// Called to broadcast changes in the scroll view's size. +- (void)scrollViewSizeDidChange:(CGSize)scrollViewSize; +// Called to broadcast changes in the content size. +- (void)scrollViewDidResetContentSize:(CGSize)contentSize; +// Called to broadcast changes in the content inset. +- (void)scrollViewDidResetContentInset:(UIEdgeInsets)contentInset; // Called to broadcast scroll offset changes due to scrolling. - (void)scrollViewDidScrollToOffset:(CGPoint)offset; // Called when a drag event with |panGesture| begins. @@ -45,6 +63,9 @@ residualVelocity:(CGPoint)velocity; // Called when the scroll view stops decelerating. - (void)scrollViewDidEndDecelerating; +// Called when the scroll view starts and ends zooming. +- (void)scrollViewDidStartZooming; +- (void)scrollViewDidEndZooming; // Called when a scroll event is interrupted (i.e. when a navigation occurs mid- // scroll). - (void)scrollWasInterrupted;
diff --git a/ios/chrome/browser/ui/main_content/main_content_ui_state.mm b/ios/chrome/browser/ui/main_content/main_content_ui_state.mm index a25607d..a1a72ae 100644 --- a/ios/chrome/browser/ui/main_content/main_content_ui_state.mm +++ b/ios/chrome/browser/ui/main_content/main_content_ui_state.mm
@@ -13,8 +13,12 @@ @interface MainContentUIState () // Redefine broadcast properties as readwrite. +@property(nonatomic, assign) CGSize scrollViewSize; +@property(nonatomic, assign) CGSize contentSize; +@property(nonatomic, assign) UIEdgeInsets contentInset; @property(nonatomic, assign) CGFloat yContentOffset; @property(nonatomic, assign, getter=isScrolling) BOOL scrolling; +@property(nonatomic, assign, getter=isZooming) BOOL zooming; @property(nonatomic, assign, getter=isDragging) BOOL dragging; // Whether the scroll view is decelerating. @property(nonatomic, assign, getter=isDecelerating) BOOL decelerating; @@ -25,8 +29,12 @@ @end @implementation MainContentUIState +@synthesize scrollViewSize = _scrollViewSize; +@synthesize contentSize = _contentSize; +@synthesize contentInset = _contentInset; @synthesize yContentOffset = _yContentOffset; @synthesize scrolling = _scrolling; +@synthesize zooming = _zooming; @synthesize dragging = _dragging; @synthesize decelerating = _decelerating; @@ -82,6 +90,18 @@ #pragma mark Public +- (void)scrollViewSizeDidChange:(CGSize)scrollViewSize { + self.state.scrollViewSize = scrollViewSize; +} + +- (void)scrollViewDidResetContentSize:(CGSize)contentSize { + self.state.contentSize = contentSize; +} + +- (void)scrollViewDidResetContentInset:(UIEdgeInsets)contentInset { + self.state.contentInset = contentInset; +} + - (void)scrollViewDidScrollToOffset:(CGPoint)offset { self.state.yContentOffset = offset.y; } @@ -110,10 +130,19 @@ self.state.decelerating = NO; } +- (void)scrollViewDidStartZooming { + self.state.zooming = YES; +} + +- (void)scrollViewDidEndZooming { + self.state.zooming = NO; +} + - (void)scrollWasInterrupted { self.state.scrolling = NO; self.state.dragging = NO; self.state.decelerating = NO; + self.state.zooming = NO; } @end
diff --git a/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm b/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm index 73561a26..5a14dbe5 100644 --- a/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm +++ b/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm
@@ -113,6 +113,11 @@ #pragma mark CRWWebViewScrollViewObserver +- (void)webViewScrollViewFrameDidChange: + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { + [self.updater scrollViewSizeDidChange:webViewScrollViewProxy.frame.size]; +} + - (void)webViewScrollViewDidScroll: (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { [self.updater scrollViewDidScrollToOffset:self.proxy.contentOffset]; @@ -138,6 +143,18 @@ [self.updater scrollViewDidEndDecelerating]; } +- (void)webViewScrollViewDidResetContentSize: + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { + [self.updater + scrollViewDidResetContentSize:webViewScrollViewProxy.contentSize]; +} + +- (void)webViewScrollViewDidResetContentInset: + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { + [self.updater + scrollViewDidResetContentInset:webViewScrollViewProxy.contentInset]; +} + #pragma mark - WebStateListObserving - (void)webStateList:(WebStateList*)webStateList
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 16e80bf..fee42b17 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -48,6 +48,8 @@ "//ios/web/public", "//ios/web/web_state:web_view_internal_creation_util", "//services/catalog/public/cpp", + "//services/network:network_service", + "//services/network/public/interfaces", "//services/service_manager", "//services/service_manager/embedder", "//services/service_manager/runner/common", @@ -548,6 +550,7 @@ "//ios/web/test:test_support", "//mojo/edk/system", "//net:test_support", + "//services/network/public/cpp", "//services/service_manager/public/cpp", "//testing/gtest", "//ui/base:test_support", @@ -558,6 +561,7 @@ "navigation/window_location_inttest.mm", "public/test/http_server_inttest.mm", "test/run_all_unittests.cc", + "url_loader_inttest.mm", "web_state/favicon_callbacks_inttest.mm", "web_state/http_auth_inttest.mm", "web_state/js/form_inttest.mm",
diff --git a/ios/web/DEPS b/ios/web/DEPS index 753981e9..d7936125 100644 --- a/ios/web/DEPS +++ b/ios/web/DEPS
@@ -5,6 +5,8 @@ "+ios/web", "+mojo/public", "+net", + "+services/network/public/interfaces/url_loader_factory.mojom.h", + "+services/network/url_loader.h", "+ui", # Needed to embed the ServiceManager in //ios/web.
diff --git a/ios/web/browser_state.mm b/ios/web/browser_state.mm index 7165042..ba88501 100644 --- a/ios/web/browser_state.mm +++ b/ios/web/browser_state.mm
@@ -6,6 +6,8 @@ #include <memory> +#include "base/bind.h" +#include "base/bind_helpers.h" #include "base/guid.h" #include "base/lazy_instance.h" #include "base/location.h" @@ -17,6 +19,9 @@ #include "ios/web/public/web_client.h" #include "ios/web/public/web_thread.h" #include "ios/web/webui/url_data_manager_ios_backend.h" +#include "net/url_request/url_request_context_getter.h" +#include "services/network/public/interfaces/url_loader_factory.mojom.h" +#include "services/network/url_loader.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/mojom/service.mojom.h" @@ -101,6 +106,52 @@ } // namespace +class BrowserState::URLLoaderFactory : public network::mojom::URLLoaderFactory { + public: + explicit URLLoaderFactory(net::URLRequestContextGetter* request_context) + : request_context_(request_context) {} + + void CreateLoaderAndStart(network::mojom::URLLoaderRequest request, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& resource_request, + network::mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override { + WebThread::PostTask( + web::WebThread::IO, FROM_HERE, + base::BindOnce(URLLoaderFactory::CreateLoaderAndStartOnIO, + request_context_, std::move(request), routing_id, + request_id, options, resource_request, + client.PassInterface(), traffic_annotation)); + } + + void Clone(network::mojom::URLLoaderFactoryRequest request) override { + NOTREACHED() << "Clone shouldn't be called on iOS"; + } + + private: + static void CreateLoaderAndStartOnIO( + scoped_refptr<net::URLRequestContextGetter> request_getter, + network::mojom::URLLoaderRequest request, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& resource_request, + network::mojom::URLLoaderClientPtrInfo client_info, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { + // Object deletes itself when the pipe or the URLRequestContext goes away. + network::mojom::URLLoaderClientPtr client(std::move(client_info)); + new network::URLLoader( + request_getter, nullptr, std::move(request), options, resource_request, + false, std::move(client), + static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation), 0, + nullptr); + } + scoped_refptr<net::URLRequestContextGetter> request_context_; +}; + // static scoped_refptr<CertificatePolicyCache> BrowserState::GetCertificatePolicyCache( BrowserState* browser_state) { @@ -146,6 +197,15 @@ } } +network::mojom::URLLoaderFactory* BrowserState::GetURLLoaderFactory() { + if (!url_loader_factory_) { + url_loader_factory_ = + std::make_unique<URLLoaderFactory>(GetRequestContext()); + } + + return url_loader_factory_.get(); +} + URLDataManagerIOSBackend* BrowserState::GetURLDataManagerIOSBackendOnIOThread() { DCHECK_CURRENTLY_ON(web::WebThread::IO);
diff --git a/ios/web/public/browser_state.h b/ios/web/public/browser_state.h index f900a3b..705c183 100644 --- a/ios/web/public/browser_state.h +++ b/ios/web/public/browser_state.h
@@ -5,6 +5,8 @@ #ifndef IOS_WEB_PUBLIC_BROWSER_STATE_H_ #define IOS_WEB_PUBLIC_BROWSER_STATE_H_ +#include <memory> + #include "base/supports_user_data.h" #include "services/service_manager/embedder/embedded_service_info.h" @@ -16,6 +18,12 @@ class URLRequestContextGetter; } +namespace network { +namespace mojom { +class URLLoaderFactory; +} +} // namespace network + namespace service_manager { class Connector; } @@ -50,6 +58,9 @@ // BrowserState. virtual net::URLRequestContextGetter* GetRequestContext() = 0; + // Returns a URLLoaderFactory that is backed by GetRequestContext. + network::mojom::URLLoaderFactory* GetURLLoaderFactory(); + // Safely cast a base::SupportsUserData to a BrowserState. Returns nullptr // if |supports_user_data| is not a BrowserState. static BrowserState* FromSupportsUserData( @@ -87,6 +98,7 @@ const base::FilePath& path); private: + class URLLoaderFactory; friend class URLDataManagerIOS; friend class URLRequestChromeJob; @@ -96,6 +108,8 @@ // Not intended for usage outside of //web. URLDataManagerIOSBackend* GetURLDataManagerIOSBackendOnIOThread(); + std::unique_ptr<URLLoaderFactory> url_loader_factory_; + // The URLDataManagerIOSBackend instance associated with this BrowserState. // Created and destroyed on the IO thread, and should be accessed only from // the IO thread.
diff --git a/ios/web/public/test/web_test.h b/ios/web/public/test/web_test.h index 2656b02..4d02c9f 100644 --- a/ios/web/public/test/web_test.h +++ b/ios/web/public/test/web_test.h
@@ -22,8 +22,10 @@ // mimics a web embedder. class WebTest : public PlatformTest { protected: - WebTest(); - explicit WebTest(std::unique_ptr<web::WebClient> web_client); + explicit WebTest(TestWebThreadBundle::Options options = + TestWebThreadBundle::Options::DEFAULT); + WebTest(std::unique_ptr<web::WebClient> web_client, + TestWebThreadBundle::Options = TestWebThreadBundle::Options::DEFAULT); ~WebTest() override; // Returns the WebClient that is used for testing.
diff --git a/ios/web/public/test/web_test.mm b/ios/web/public/test/web_test.mm index c031f5a..4f85f6ff 100644 --- a/ios/web/public/test/web_test.mm +++ b/ios/web/public/test/web_test.mm
@@ -24,10 +24,13 @@ } }; -WebTest::WebTest() : WebTest(base::WrapUnique(new TestWebClient)) {} +WebTest::WebTest(TestWebThreadBundle::Options options) + : WebTest(base::WrapUnique(new TestWebClient), options) {} -WebTest::WebTest(std::unique_ptr<web::WebClient> web_client) +WebTest::WebTest(std::unique_ptr<web::WebClient> web_client, + TestWebThreadBundle::Options options) : web_client_(std::move(web_client)), + thread_bundle_(options), crash_observer_(std::make_unique<WebTestRenderProcessCrashObserver>()) {} WebTest::~WebTest() {}
diff --git a/ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h b/ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h index 4c131d5..91e264b 100644 --- a/ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h +++ b/ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h
@@ -66,6 +66,8 @@ // information look at the UIScrollViewDelegate documentation. @protocol CRWWebViewScrollViewObserver<NSObject> @optional +- (void)webViewScrollViewFrameDidChange: + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (void)webViewScrollViewDidScroll: (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (void)webViewScrollViewWillBeginDragging: @@ -87,12 +89,18 @@ (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (void)webViewScrollViewDidResetContentSize: (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; +- (void)webViewScrollViewDidResetContentInset: + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; // The equivalent in UIScrollViewDelegate also takes a parameter (UIView*)view, // but CRWWebViewScrollViewObserver doesn't expose it for flexibility of future // implementation. - (void)webViewScrollViewWillBeginZooming: (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; +- (void)webViewScrollViewDidEndZooming: + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy + atScale:(CGFloat)scale; + @end // A protocol to be implemented by objects to listen for changes to the
diff --git a/ios/web/url_loader_inttest.mm b/ios/web/url_loader_inttest.mm new file mode 100644 index 0000000..ce8ce0bec --- /dev/null +++ b/ios/web/url_loader_inttest.mm
@@ -0,0 +1,62 @@ +// 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. + +#include <memory> + +#include "base/run_loop.h" +#include "base/test/bind_test_util.h" +#import "ios/web/public/test/web_test.h" +#import "ios/web/public/web_client.h" +#import "ios/web/public/web_state/web_state.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/resource_response.h" +#include "services/network/public/cpp/simple_url_loader.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace web { + +class URLLoaderTest : public WebTest { + protected: + URLLoaderTest() : WebTest(TestWebThreadBundle::Options::IO_MAINLOOP) {} + + protected: + net::EmbeddedTestServer server_; +}; + +// Tests that basic URLLoader wrapper works. +TEST_F(URLLoaderTest, Basic) { + server_.AddDefaultHandlers(FILE_PATH_LITERAL(base::FilePath())); + ASSERT_TRUE(server_.Start()); + + std::unique_ptr<network::ResourceRequest> request = + std::make_unique<network::ResourceRequest>(); + request->url = server_.GetURL("/echo"); + auto loader = network::SimpleURLLoader::Create(std::move(request), + TRAFFIC_ANNOTATION_FOR_TESTS); + std::string result; + base::RunLoop run_loop; + loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + GetBrowserState()->GetURLLoaderFactory(), + base::BindLambdaForTesting( + [&](std::unique_ptr<std::string> response_body) { + if (response_body) + result = *response_body; + run_loop.Quit(); + })); + run_loop.Run(); + + EXPECT_EQ(0, loader->NetError()); + EXPECT_EQ(result, "Echo"); + auto* response_info = loader->ResponseInfo(); + ASSERT_TRUE(!!response_info); + ASSERT_TRUE(!!response_info->headers); + EXPECT_EQ(200, response_info->headers->response_code()); +} + +} // namespace web
diff --git a/ios/web/web_state/ui/crw_web_view_scroll_view_proxy.mm b/ios/web/web_state/ui/crw_web_view_scroll_view_proxy.mm index b6be344..b8275ee 100644 --- a/ios/web/web_state/ui/crw_web_view_scroll_view_proxy.mm +++ b/ios/web/web_state/ui/crw_web_view_scroll_view_proxy.mm
@@ -289,10 +289,17 @@ [_observers webViewScrollViewWillBeginZooming:self]; } +- (void)scrollViewDidEndZooming:(UIScrollView*)scrollView + withView:(UIView*)view + atScale:(CGFloat)scale { + DCHECK_EQ(_scrollView, scrollView); + [_observers webViewScrollViewDidEndZooming:self atScale:scale]; +} + #pragma mark - + (NSArray*)scrollViewObserverKeyPaths { - return @[ @"contentSize" ]; + return @[ @"frame", @"contentSize", @"contentInset" ]; } - (void)startObservingScrollView:(UIScrollView*)scrollView { @@ -310,8 +317,12 @@ change:(NSDictionary*)change context:(void*)context { DCHECK_EQ(object, _scrollView); + if ([keyPath isEqualToString:@"frame"]) + [_observers webViewScrollViewFrameDidChange:self]; if ([keyPath isEqualToString:@"contentSize"]) [_observers webViewScrollViewDidResetContentSize:self]; + if ([keyPath isEqualToString:@"contentInset"]) + [_observers webViewScrollViewDidResetContentInset:self]; } @end
diff --git a/ios/web/web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm b/ios/web/web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm index 60f14e9..1f9f70ca 100644 --- a/ios/web/web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm +++ b/ios/web/web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm
@@ -24,6 +24,9 @@ mockScrollView_ = [OCMockObject niceMockForClass:[UIScrollView class]]; webViewScrollViewProxy_ = [[CRWWebViewScrollViewProxy alloc] init]; } + ~CRWWebViewScrollViewProxyTest() override { + [webViewScrollViewProxy_ setScrollView:nil]; + } id mockScrollView_; CRWWebViewScrollViewProxy* webViewScrollViewProxy_; }; @@ -261,4 +264,32 @@ [mockScrollView_ verify]; } +// Tests that frame changes are communicated to observers. +TEST_F(CRWWebViewScrollViewProxyTest, FrameDidChange) { + UIScrollView* scroll_view = [[UIScrollView alloc] initWithFrame:CGRectZero]; + [webViewScrollViewProxy_ setScrollView:scroll_view]; + id mock_delegate = [OCMockObject + niceMockForProtocol:@protocol(CRWWebViewScrollViewProxyObserver)]; + [webViewScrollViewProxy_ addObserver:mock_delegate]; + [[mock_delegate expect] + webViewScrollViewFrameDidChange:webViewScrollViewProxy_]; + scroll_view.frame = CGRectMake(1, 2, 3, 4); + [mock_delegate verify]; + [webViewScrollViewProxy_ setScrollView:nil]; +} + +// Tests that contentInset changes are communicated to observers. +TEST_F(CRWWebViewScrollViewProxyTest, ContentInsetDidChange) { + UIScrollView* scroll_view = [[UIScrollView alloc] initWithFrame:CGRectZero]; + [webViewScrollViewProxy_ setScrollView:scroll_view]; + id mock_delegate = [OCMockObject + niceMockForProtocol:@protocol(CRWWebViewScrollViewProxyObserver)]; + [webViewScrollViewProxy_ addObserver:mock_delegate]; + [[mock_delegate expect] + webViewScrollViewDidResetContentInset:webViewScrollViewProxy_]; + scroll_view.contentInset = UIEdgeInsetsMake(0, 1, 2, 3); + [mock_delegate verify]; + [webViewScrollViewProxy_ setScrollView:nil]; +} + } // namespace
diff --git a/media/README.md b/media/README.md index 475ecca..33d71df 100644 --- a/media/README.md +++ b/media/README.md
@@ -74,7 +74,7 @@ # mojo -TODO(xhwang): Fill in this section. +See [media/mojo documentation](/media/mojo).
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 7779707..a0b5d16 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -189,7 +189,7 @@ const base::Feature kOverlayFullscreenVideo{"overlay-fullscreen-video", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enable Picture in Picture. +// Enable Picture-in-Picture. const base::Feature kPictureInPicture{"PictureInPicture", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 27db985..66910bf 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -870,9 +870,6 @@ mojom::MediaMetricsProviderPtr media_metrics_provider_; - base::Callback<mojom::VideoDecodeStatsRecorderPtr()> - create_decode_stats_recorder_cb_; - base::Optional<bool> stale_state_override_for_testing_; DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc index 3b11530d..2141438 100644 --- a/media/gpu/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/dxva_video_decode_accelerator_win.cc
@@ -201,6 +201,124 @@ uint64_t g_last_process_output_time; HRESULT g_last_device_removed_reason; +// Certain AMD GPU drivers like R600, R700, Evergreen and Cayman and some second +// generation Intel GPU drivers crash if we create a video device with a +// resolution higher then 1920 x 1088. This function checks if the GPU is in +// this list and if yes returns true. +bool IsLegacyGPU(ID3D11Device* device) { + constexpr int kAMDGPUId1 = 0x1002; + constexpr int kAMDGPUId2 = 0x1022; + constexpr int kIntelGPU = 0x8086; + + Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device; + HRESULT hr = device->QueryInterface(IID_PPV_ARGS(&dxgi_device)); + if (FAILED(hr)) + return true; + + Microsoft::WRL::ComPtr<IDXGIAdapter> adapter; + hr = dxgi_device->GetAdapter(adapter.GetAddressOf()); + if (FAILED(hr)) + return true; + + DXGI_ADAPTER_DESC adapter_desc = {}; + hr = adapter->GetDesc(&adapter_desc); + if (FAILED(hr)) + return true; + + // We check if the device is an Intel or an AMD device and whether it is in + // the global list defined by the g_AMDUVD3GPUList and g_IntelLegacyGPUList + // arrays above. If yes then the device is treated as a legacy device. + if (adapter_desc.VendorId == kAMDGPUId1 || + adapter_desc.VendorId == kAMDGPUId2) { + for (size_t i = 0; i < arraysize(g_AMDUVD3GPUList); i++) { + if (adapter_desc.DeviceId == g_AMDUVD3GPUList[i]) + return true; + } + } else if (adapter_desc.VendorId == kIntelGPU) { + for (size_t i = 0; i < arraysize(g_IntelLegacyGPUList); i++) { + if (adapter_desc.DeviceId == g_IntelLegacyGPUList[i]) + return true; + } + } + + return false; +} + +// Returns true if a ID3D11VideoDecoder can be created for |resolution_to_test| +// on the given |video_device|. +bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test, + const GUID& decoder_guid, + ID3D11VideoDevice* video_device) { + D3D11_VIDEO_DECODER_DESC desc = {}; + desc.Guid = decoder_guid; + desc.SampleWidth = resolution_to_test.width(); + desc.SampleHeight = resolution_to_test.height(); + desc.OutputFormat = DXGI_FORMAT_NV12; + UINT config_count = 0; + HRESULT hr = video_device->GetVideoDecoderConfigCount(&desc, &config_count); + if (FAILED(hr) || config_count == 0) + return false; + + D3D11_VIDEO_DECODER_CONFIG config = {}; + hr = video_device->GetVideoDecoderConfig(&desc, 0, &config); + if (FAILED(hr)) + return false; + + Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder; + hr = video_device->CreateVideoDecoder(&desc, &config, + video_decoder.GetAddressOf()); + return !!video_decoder; +} + +// Returns a tuple of (LandscapeMax, PortraitMax). If landscape maximum can not +// be computed, the value of |default_max| is returned for the landscape maximum +// and a zero size value is returned for portrait max (erring conservatively). +using ResolutionPair = std::pair<gfx::Size, gfx::Size>; +ResolutionPair GetMaxResolutionsForGUIDs( + const gfx::Size& default_max, + ID3D11VideoDevice* video_device, + const std::vector<GUID>& valid_guids, + const std::vector<gfx::Size>& resolutions_to_test) { + TRACE_EVENT0("gpu,startup", "GetMaxResolutionsForGUIDs"); + ResolutionPair result(default_max, gfx::Size()); + + // Enumerate supported video profiles and look for the profile. + GUID decoder_guid = GUID_NULL; + UINT profile_count = video_device->GetVideoDecoderProfileCount(); + for (UINT profile_idx = 0; profile_idx < profile_count; profile_idx++) { + GUID profile_id = {}; + if (SUCCEEDED( + video_device->GetVideoDecoderProfile(profile_idx, &profile_id)) && + std::find(valid_guids.begin(), valid_guids.end(), profile_id) != + valid_guids.end()) { + decoder_guid = profile_id; + break; + } + } + if (decoder_guid == GUID_NULL) + return result; + + // Verify input is in ascending order by height. + DCHECK(std::is_sorted(resolutions_to_test.begin(), resolutions_to_test.end(), + [](const gfx::Size& a, const gfx::Size& b) { + return a.height() < b.height(); + })); + + for (const auto& res : resolutions_to_test) { + if (!IsResolutionSupportedForDevice(res, decoder_guid, video_device)) + break; + result.first = res; + } + + // The max supported portrait resolution should be just be a w/h flip of the + // max supported landscape resolution. + gfx::Size flipped(result.first.height(), result.first.width()); + if (IsResolutionSupportedForDevice(flipped, decoder_guid, video_device)) + result.second = flipped; + + return result; +} + } // namespace namespace media { @@ -1305,9 +1423,7 @@ TRACE_EVENT0("gpu,startup", "DXVAVideoDecodeAccelerator::GetSupportedProfiles"); - // TODO(henryhsu): Need to ensure the profiles are actually supported. SupportedProfiles profiles; - for (const wchar_t* mfdll : kMediaFoundationVideoDecoderDLLs) { if (!::GetModuleHandle(mfdll)) { // Windows N is missing the media foundation DLLs unless the media @@ -1316,20 +1432,86 @@ return profiles; } } + + // On Windows 7 the maximum resolution supported by media foundation is + // 1920 x 1088. We use 1088 to account for 16x16 macroblocks. + ResolutionPair max_h264_resolutions(gfx::Size(1920, 1088), gfx::Size()); + + // VPX has no default resolutions since it may not even be supported. + ResolutionPair max_vpx_resolutions; + + if (base::win::GetVersion() > base::win::VERSION_WIN7) { + // To detect if a driver supports the desired resolutions, we try and create + // a DXVA decoder instance for that resolution and profile. If that succeeds + // we assume that the driver supports decoding for that resolution. + Microsoft::WRL::ComPtr<ID3D11Device> device = + gl::QueryD3D11DeviceObjectFromANGLE(); + + // Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while + // creating surfaces larger than 1920 x 1088. + if (device && !IsLegacyGPU(device.Get())) { + Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device; + if (SUCCEEDED(device.CopyTo(IID_PPV_ARGS(&video_device)))) { + max_h264_resolutions = GetMaxResolutionsForGUIDs( + max_h264_resolutions.first, video_device.Get(), + {DXVA2_ModeH264_E, DXVA2_Intel_ModeH264_E}, + {gfx::Size(2560, 1440), gfx::Size(3840, 2160), + gfx::Size(4096, 2160), gfx::Size(4096, 2304)}); + + // Despite the name this is the GUID for VP8/VP9. + if (preferences.enable_accelerated_vpx_decode && + !workarounds.disable_accelerated_vpx_decode) { + max_vpx_resolutions = GetMaxResolutionsForGUIDs( + max_vpx_resolutions.first, video_device.Get(), + {D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0}, + {gfx::Size(4096, 2160), gfx::Size(4096, 2304), + gfx::Size(7680, 4320)}); + } + } + } + } + for (const auto& supported_profile : kSupportedProfiles) { - if ((!preferences.enable_accelerated_vpx_decode || - workarounds.disable_accelerated_vpx_decode) && - (supported_profile >= VP8PROFILE_MIN) && - (supported_profile <= VP9PROFILE_MAX)) { + const bool kIsVPX = supported_profile >= VP8PROFILE_MIN && + supported_profile <= VP9PROFILE_MAX; + + // Skip adding VPX profiles if it's not supported or disabled. + if (kIsVPX && max_vpx_resolutions.first.IsEmpty()) continue; + + const bool kIsH264 = supported_profile >= H264PROFILE_MIN && + supported_profile <= H264PROFILE_MAX; + DCHECK(kIsH264 || kIsVPX); + + // Windows Media Foundation H.264 decoding does not support decoding videos + // with any dimension smaller than 48 pixels: + // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 + // + // TODO(dalecurtis): These values are too low. We should only be using + // hardware decode for videos above ~360p, see http://crbug.com/684792. + const gfx::Size kMinResolution = + kIsH264 ? gfx::Size(48, 48) : gfx::Size(16, 16); + + { + SupportedProfile profile; + profile.profile = supported_profile; + profile.min_resolution = kMinResolution; + profile.max_resolution = + kIsH264 ? max_h264_resolutions.first : max_vpx_resolutions.first; + profiles.push_back(profile); } - SupportedProfile profile; - profile.profile = supported_profile; - profile.min_resolution = GetMinResolution(supported_profile); - profile.max_resolution = GetMaxResolution(supported_profile); - profiles.push_back(profile); + const gfx::Size kPortraitMax = + kIsH264 ? max_h264_resolutions.second : max_vpx_resolutions.second; + if (!kPortraitMax.IsEmpty()) { + SupportedProfile profile; + profile.profile = supported_profile; + profile.min_resolution = kMinResolution; + profile.max_resolution = kPortraitMax; + profiles.push_back(profile); + } } + return profiles; } @@ -1348,196 +1530,6 @@ } } -// static -gfx::Size DXVAVideoDecodeAccelerator::GetMinResolution( - VideoCodecProfile profile) { - TRACE_EVENT0("gpu,startup", "DXVAVideoDecodeAccelerator::GetMinResolution"); - - // TODO(dalecurtis): These values are too low. We should only be using - // hardware decode for videos above ~360p, see http://crbug.com/684792. - - if (profile >= H264PROFILE_BASELINE && profile <= H264PROFILE_HIGH) { - // Windows Media Foundation H.264 decoding does not support decoding videos - // with any dimension smaller than 48 pixels: - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 - return gfx::Size(48, 48); - } - - // TODO(dalecurtis): Detect this properly for VP8/VP9 profiles. - return gfx::Size(16, 16); -} - -// static -gfx::Size DXVAVideoDecodeAccelerator::GetMaxResolution( - VideoCodecProfile profile) { - TRACE_EVENT0("gpu,startup", "DXVAVideoDecodeAccelerator::GetMaxResolution"); - - // Computes and caches the maximum resolution since it's expensive to - // determine and this function is called for every profile in - // kSupportedProfiles. - - if (profile >= H264PROFILE_BASELINE && profile <= H264PROFILE_HIGH) { - const gfx::Size kDefaultMax = gfx::Size(1920, 1088); - - // On Windows 7 the maximum resolution supported by media foundation is - // 1920 x 1088. We use 1088 to account for 16x16 macroblocks. - if (base::win::GetVersion() == base::win::VERSION_WIN7) - return kDefaultMax; - - static const gfx::Size kCachedH264Resolution = GetMaxResolutionForGUIDs( - kDefaultMax, {DXVA2_ModeH264_E, DXVA2_Intel_ModeH264_E}, - {gfx::Size(2560, 1440), gfx::Size(3840, 2160), gfx::Size(4096, 2160), - gfx::Size(4096, 2304)}); - return kCachedH264Resolution; - } - - // Despite the name this is the GUID for VP8/VP9. - static const gfx::Size kCachedVPXResolution = GetMaxResolutionForGUIDs( - gfx::Size(4096, 2160), {D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0}, - {gfx::Size(4096, 2304), gfx::Size(7680, 4320)}); - return kCachedVPXResolution; -} - -gfx::Size DXVAVideoDecodeAccelerator::GetMaxResolutionForGUIDs( - const gfx::Size& default_max, - const std::vector<GUID>& valid_guids, - const std::vector<gfx::Size>& resolutions_to_test) { - TRACE_EVENT0("gpu,startup", - "DXVAVideoDecodeAccelerator::GetMaxResolutionForGUIDs"); - gfx::Size max_resolution = default_max; - - // To detect if a driver supports the desired resolutions, we try and create - // a DXVA decoder instance for that resolution and profile. If that succeeds - // we assume that the driver supports H/W H.264 decoding for that resolution. - HRESULT hr = E_FAIL; - Microsoft::WRL::ComPtr<ID3D11Device> device; - { - TRACE_EVENT0("gpu,startup", - "GetMaxResolutionForGUIDs. QueryDeviceObjectFromANGLE"); - - device = gl::QueryD3D11DeviceObjectFromANGLE(); - if (!device) - return max_resolution; - } - - // Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while - // creating surfaces larger than 1920 x 1088. - if (IsLegacyGPU(device.Get())) - return max_resolution; - - Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device; - hr = device.CopyTo(IID_PPV_ARGS(&video_device)); - if (FAILED(hr)) - return max_resolution; - - GUID decoder_guid = GUID_NULL; - { - TRACE_EVENT0("gpu,startup", "GetMaxResolutionForGUIDs. GUID search begin"); - // Enumerate supported video profiles and look for the H264 profile. - UINT profile_count = video_device->GetVideoDecoderProfileCount(); - for (UINT profile_idx = 0; profile_idx < profile_count; profile_idx++) { - GUID profile_id = {}; - hr = video_device->GetVideoDecoderProfile(profile_idx, &profile_id); - if (SUCCEEDED(hr) && (std::find(valid_guids.begin(), valid_guids.end(), - profile_id) != valid_guids.end())) { - decoder_guid = profile_id; - break; - } - } - if (decoder_guid == GUID_NULL) - return max_resolution; - } - - { - TRACE_EVENT0("gpu,startup", - "GetMaxResolutionForGUIDs. Resolution search begin"); - - for (auto& res : resolutions_to_test) { - D3D11_VIDEO_DECODER_DESC desc = {}; - desc.Guid = decoder_guid; - desc.SampleWidth = res.width(); - desc.SampleHeight = res.height(); - desc.OutputFormat = DXGI_FORMAT_NV12; - UINT config_count = 0; - hr = video_device->GetVideoDecoderConfigCount(&desc, &config_count); - if (FAILED(hr) || config_count == 0) - return max_resolution; - - D3D11_VIDEO_DECODER_CONFIG config = {}; - hr = video_device->GetVideoDecoderConfig(&desc, 0, &config); - if (FAILED(hr)) - return max_resolution; - - Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder; - hr = video_device->CreateVideoDecoder(&desc, &config, - video_decoder.GetAddressOf()); - if (!video_decoder) - return max_resolution; - - max_resolution = res; - } - } - - return max_resolution; -} - -// static -bool DXVAVideoDecodeAccelerator::IsLegacyGPU(ID3D11Device* device) { - static const int kAMDGPUId1 = 0x1002; - static const int kAMDGPUId2 = 0x1022; - static const int kIntelGPU = 0x8086; - - static bool legacy_gpu = true; - // This flag ensures that we determine the GPU type once. - static bool legacy_gpu_determined = false; - - if (legacy_gpu_determined) - return legacy_gpu; - - legacy_gpu_determined = true; - - Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device; - HRESULT hr = device->QueryInterface(IID_PPV_ARGS(&dxgi_device)); - if (FAILED(hr)) - return legacy_gpu; - - Microsoft::WRL::ComPtr<IDXGIAdapter> adapter; - hr = dxgi_device->GetAdapter(adapter.GetAddressOf()); - if (FAILED(hr)) - return legacy_gpu; - - DXGI_ADAPTER_DESC adapter_desc = {}; - hr = adapter->GetDesc(&adapter_desc); - if (FAILED(hr)) - return legacy_gpu; - - // We check if the device is an Intel or an AMD device and whether it is in - // the global list defined by the g_AMDUVD3GPUList and g_IntelLegacyGPUList - // arrays above. If yes then the device is treated as a legacy device. - if ((adapter_desc.VendorId == kAMDGPUId1) || - adapter_desc.VendorId == kAMDGPUId2) { - { - TRACE_EVENT0("gpu,startup", - "DXVAVideoDecodeAccelerator::IsLegacyGPU. AMD check"); - for (size_t i = 0; i < arraysize(g_AMDUVD3GPUList); i++) { - if (adapter_desc.DeviceId == g_AMDUVD3GPUList[i]) - return legacy_gpu; - } - } - } else if (adapter_desc.VendorId == kIntelGPU) { - { - TRACE_EVENT0("gpu,startup", - "DXVAVideoDecodeAccelerator::IsLegacyGPU. Intel check"); - for (size_t i = 0; i < arraysize(g_IntelLegacyGPUList); i++) { - if (adapter_desc.DeviceId == g_IntelLegacyGPUList[i]) - return legacy_gpu; - } - } - } - legacy_gpu = false; - return legacy_gpu; -} - bool DXVAVideoDecodeAccelerator::InitDecoder(VideoCodecProfile profile) { HMODULE decoder_dll = NULL;
diff --git a/media/gpu/dxva_video_decode_accelerator_win.h b/media/gpu/dxva_video_decode_accelerator_win.h index f669f50..dc960c0 100644 --- a/media/gpu/dxva_video_decode_accelerator_win.h +++ b/media/gpu/dxva_video_decode_accelerator_win.h
@@ -144,28 +144,6 @@ BIND }; - // Returns the minimum resolution for the |profile| passed in. - static gfx::Size GetMinResolution(VideoCodecProfile profile); - - // Returns the maximum resolution for the |profile| passed in. - static gfx::Size GetMaxResolution(VideoCodecProfile profile); - - // Returns the maximum resolution for by attempting to create a decoder for - // each of the resolutions in |resolutions_to_test| for the first decoder - // matching a GUID from |valid_guids|. |resolutions_to_test| should be ordered - // from smallest to largest resolution. |default_max_resolution| will be - // returned if any errors occur during the process. - static gfx::Size GetMaxResolutionForGUIDs( - const gfx::Size& default_max_resolution, - const std::vector<GUID>& valid_guids, - const std::vector<gfx::Size>& resolutions_to_test); - - // Certain AMD GPU drivers like R600, R700, Evergreen and Cayman and - // some second generation Intel GPU drivers crash if we create a video - // device with a resolution higher then 1920 x 1088. This function - // checks if the GPU is in this list and if yes returns true. - static bool IsLegacyGPU(ID3D11Device* device); - // Creates and initializes an instance of the D3D device and the // corresponding device manager. The device manager instance is eventually // passed to the IMFTransform interface implemented by the decoder.
diff --git a/media/mojo/README.md b/media/mojo/README.md new file mode 100644 index 0000000..3824154 --- /dev/null +++ b/media/mojo/README.md
@@ -0,0 +1,318 @@ +# media/mojo + +This folder contains mojo interfaces, clients and implementations that extend +the core "media" target to support most out-of-process use cases, including +Media Player, Metrics (WatchTime), etc. + +Currently the “media” target does not depend on mojo, so that other applications +can use the “media” target without having to pull in mojo dependency. + +[TOC] + +## Media Player + +### Media Components + +Media Player (`WebMediaPlayer`) supports HTML5 \<video\> playback in Chromium. +Internally, it depends on many **media components** to perform some specific +tasks, e.g. **media renderer**, **audio decoder**, **video decoder**, and +**content decryption module** (CDM). A CDM is required for a *media renderer*, +*audio decoder* or *video decoder* to handle protected content. See more details +in the general [media documentation](/media). + +While most of HTML5 media player stack and Encrypted Media Extensions (EME) +stack live in the sandboxed render process (e.g. for security reasons), there +are some cases where some media components must live in a different process. +For example: + +* A hardware-based media renderer, where all audio/video decoding and rendering + happens in hardware, which is not accessible in the sandboxed render process. +* A hardware based video decoder, where the hardware decoding libraries are not + accessible in the sandboxed render process. +* On Android, a media component depends on Android Java API, which is not + accessible in the sandboxed render process. +* A CDM contains third-party code and should run in its own sandboxed process. + +Here we provide a generic framework to support most out-of-process (OOP) media +component use cases in Chromium. + +### Media Player Mojo Interfaces + +We use mojom interfaces as the transport layer of each media component to +support hosting them remotely. These interfaces are called **media player mojo +interfaces**. They are very similar to their C++ counterparts: + +* `media::Renderer` -> `media::mojom::Renderer` +* `media::AudioDecoder` -> `media::mojom::AudioDecoder` +* `media::VideoDecoder` -> `media::mojom::VideoDecoder` +* `media::ContentDecryptionModule` -> `media::mojom::ContentDecryptionModule` +* `media::Decryptor` -> `media::mojom::Decryptor` + +### Enable Remote Media Components + +Standard clients and implementations of these interfaces are provided. For +example, for `media::Renderer`, `MojoRenderer` implements `media::Renderer`, and +forwards calls to a `media::mojom::RendererPtr`. `MojoRendererService` +implements `media::mojom::Renderer`, and can host any `media::Renderer` +implementation. + +Remote media components can be easily enabled and seamlessly integrated in the +current media pipeline. Simply set the gn argument `mojo_media_services` to +specify which remote media components you want to enable. For example, with the +following gn arguments, the media pipeline will enable `MojoRenderer` and +`MojoCdm`: +``` +enable_mojo_media = true +mojo_media_services = ["renderer", "cdm"] +``` +Note that you must set `enable_mojo_media` first. Also, some remote media +components are also controlled by run time features, e.g. `media::kMojoCdm`. + +### Media Mojo Interface Factory + +`media::mojom::InterfaceFactory` has factory methods like `CreateRenderer()`, +`CreateCdm()` etc. It is used to request media player mojo interfaces. + +In the render process, each `RenderFrameImpl` has a +`media::mojom::InterfaceFactoryPtr` which is used to request all media player +mojo interfaces for that frame from the browser process. In the browser process, +each `RenderFrameHostImpl` owns a `MediaInterfaceProxy`, which implements +`media::mojom::InterfaceFactory`. + +`MediaInterfaceProxy` is a central hub for handling media player mojo interface +requests. By default it will forward all the requests to the +[`MediaService`](#MediaService). But it also has the flexibility to handle some +special or more complicated use cases. For example, on desktop platforms, when +library CDM is enabled, the `media::mojom::ContentDecryptionModule` request will +be forwarded to the [`CdmService`](#CdmService) running in its own CDM (utility) +process. For another example, on Android, the `media::mojom::Renderer` request +is handled in the `RenderFrameHostImpl` context directly by creating +`MediaPlayerRenderer` in the browser process, even though the `MediaService` is +configured to run in the GPU process. + +Note that `media::mojom::InterfaceFactory` interface is reused in the +communication between `MediaInterfaceProxy` and `MediaService` (see +[below](#Site-Isolation)). + +### MediaService + +The MediaService is a mojo `service_manager::Service` that provides media player +mojo interface implementations. It comes with some nice benefits. + +#### Flexible Process Model + +Different platforms or products have different requirements on where the remote +media components should run. For example, a hardware decoder typically should +run in the GPU process. The `ServiceManagerContext` provides the ability to run +a service_manager::Service in-process (browser), out-of-process (utility) or in +the GPU process. Therefore, by using a `MediaService`, it’s very easy to support +hosting remote media components interfaces in most common Chromium process types +(Browser/Utility/GPU). This can by set using the gn argument `mojo_media_host`, +e.g. +``` +mojo_media_host = "browser" or “gpu” or “utility” +``` + +MediaService is registered in `ServiceManagerContext` using `kMediaServiceName`. +`mojo_media_host` is checked to decide in which process the service is +registered to run. + +#### Connects Different Media Components + +Some remote media components depend on other components to work. For example, a +Renderer, an audio decoder or a video decoder needs a CDM to be able to handle +encrypted streams. Typically there's a `SetCdm()` call to connect the renderer +or decoder with the CDM. If, for example, a Renderer interface and a CDM +interface are hosted separately, then it will be hard to implement the +`SetCdm()` call. It would require an object or entity that are aware of both +sides to be able to connect them. `MediaService` handles this internally, and is + actually serving as such an object or entity, so you don’t have to reinvent + the wheel. See more details [below](#Using-CdmContext). + +#### Customization through MojoMediaClient + +`MediaService` provides everything needed to host an OOP media component, but +it doesn’t provide the media component itself. It’s up to the client of +`MediaService` to provide the concrete media component implementations. + +The `MojoMediaClient` interface provides a way for `MediaService` clients to +provide concrete media components’ implementations. When `MediaService` is +created, a `MojoMediaClient` must be passed in so that `MediaService` knows how +to create the media components. + +For example, ChromeCast uses `MediaService` to host a media Renderer and a CDM +in the browser process, and it provides the `CastRenderer` and `CastCdm` through +`CastMojoMediaClient`, a `MojoMediaClient` implementation. Note that this +overriding mechanism is not implemented everywhere. It’s trivial to add the +support and we’ll only add it when we need it. + +#### Site Isolation + +In Blink, both media element and EME MediaKeys belong to a `WebLocalFrame`. In +Chromium, this translates to media player and CDM belonging to a `RenderFrame`. +In the render process, this is clear. However, when hosting all remote media +components in a single `MediaService` (service manager only supports one service +instance per process), the Frame boundary could get fuzzy. This will be +especially dangerous for media components that interact with each other. +For example, a Renderer from foo.com lives in the same MediaService instance as +a CDM from bar.net. It would be wrong if the bar.net CDM is set on the foo.com +Renderer to handle decryption. + +To prevent this from happening, we introduce an additional layer to simulate +the `RenderFrame` boundary. A MediaService hosts multiple InterfaceFactory +(one per `RenderFrame`), and each InterfaceFactory creates and manages media +components it creates. + +For this reason, `media::mojom::InterfaceFactory` interface is reused in the +communication between `MediaInterfaceProxy` and `MediaService`. + +> Note: there are plans to split apart the responsibilities of +`media::mojom::InterfaceFactory` to make it clear which interfaces are used +where. + +#### Support Other Clients + +`MediaService`, as a `service_manager::Service`, can be used by clients other +than the media player in the render process. For example, we could have another +(mojo) service that handles audio data and wants to play it in a media Renderer. +Since `MediaService` is a mojo service, it’s very convenient for any other mojo +service to connect to it through a `service_manager::mojom::Connector` and use +the remote media Renderer it hosts. + +### CdmService + +Although `MediaService` supports `media::mojom::CDM`, in some cases (e.g. +library CDM on desktop) the remote CDM needs to run in its own process, +typically for security reasons. `CdmService` is introduced to handle this. It +also implements `service_manager::Service`, and is registered in +`ServiceManagerContext` using `kCdmServiceName`. Currently it’s always +registered to run in the utility process (with CDM sandbox type). `CdmService` +also has additional support on library CDM, e.g. loading the library CDM etc. +Note that `CdmService` only supports `media::mojom::CDM` and does NOT support +other media player mojo interfaces. + +### Mojo CDM and Mojo Decryptor + +Mojo CDM is special among all media player mojo interfaces because it is needed +by all local/remote media components to handle encrypted buffers: + +1. Local media components like `DecryptingDemuxerStream`, + `DecryptingAudioDecoder` and `DecryptingVideoDecoder`. +2. Remote media components hosted in `MediaService`, e.g. by + `MojoRendererService`, `MojoAudioDecoderService` and + `MojoVideoDecoderService`. +3. Legacy remote media components like `AndroidVideoDecodeAccelerator`. + +At the JavaScript layer, the media player and MediaKeys are connected via +[`setMediaKeys()`](https://w3c.github.io/encrypted-media/#dom-htmlmediaelement-setmediakeys). +This is implemented by `SetCdm()` in the render process. + +A media component can use a CDM in two ways. + +#### Using a Decryptor (via CdmContext) + +Some CDM provides a `Decryptor` implementation, which supports decrypting +methods directly, e.g. `Decrypt()`, `DecryptAndDecode()` etc. Both the +`AesDecryptor` and library CDM support the `Decryptor` interface. + +In the case of a remote CDM, e.g. hosted by `MojoCdmService` in `MediaService` +or `CdmService`, if the remote CDM supports the `Decryptor` interface, the +`MojoCdm` will also support the `Decryptor` interface, implemented by +`MojoDecryptor`, which set up a new message pipe to forward all `Decryptor` +calls to the `Decryptor` in the remote CDM. + +#### Using CdmContext + +In some cases the media component is set to work with a specific CDM. For +example, on Android, MediaCodec-based decoders (e.g. `MediaCodecAudioDecoder` +and `AndroidVideoDecodeAccelerator`) can only use MediaDrm-based CDM via +`MediaDrmBridgeCdmContext`. The media component and the CDM must live in the +same process because the interaction of these two are typically happening deep +at the OS level. In theory, they can both live in the render process. But in +practice, typically both the CDM and the media component are hosted by the +MediaService in a remote (e.g. GPU) process. + +To be able to attach a remote CDM with a remote media component, each +`InterfaceFactoryImpl` instance (corresponding to one `RenderFrame`) in the +`MediaService` maintains a `MojoCdmServiceContext` that keeps track of all +remote CDMs created for the `RenderFrame`. Each remote CDM is assigned a unique +CDM ID, which is sent back to the `MojoCdm` in the render process. In the render +process, when `SetCdm()` is called, the CDM ID is passed to the local media +component (e.g. `MojoRenderer`), which is forwarded the remote media component +(e.g. `MojoRendererService`). The remote media component will talk to +`MojoCdmServiceContext` to get the `CdmContext` associated with the CDM ID, and +complete the connection. + +### Secure Auxiliary Services + +Media components often need other services to work. In the render process, the +local media components get services from content layer through the `MediaClient` +interface. In `MediaService` and `CdmService`, remote media components get +services from the through **secure auxiliary services**. + +Note that as a `service_manager::Service`, `MediaService` and `CdmService` can +always connect to other `service_manager::Service` hosted by the service_manager +through the `Connector` interface. However, these are generic services that +doesn’t belong to any individual `RenderFrame`, or even user profile. + +Some services do require `RenderFrame` or user profile identity, e.g. file +system. Since media components all belong to a given `RenderFrame`, we must +maintain the frame identity when accessing these services for security reasons. +These services are called secure auxiliary services. `FrameServiceBase` is a +base class for all secure auxiliary services to help manage the lifetime of +these services (e.g. to handle navigation). + +In `MediaInterfaceProxy`, when we request `media::mojom::InterfaceFactory` in +the `MediaService` or `CdmService`, we call `GetFrameServices()` to configure +which secure auxiliary services are exposed to the remote components over the +separate `service_manager::mojom::InterfaceProvider`. + +Currently only the remote CDM needs secure auxiliary services. This is a list of +currently supported services: + +* `OutputProtection`: to check output protection status +* `PlatformVerification`: to check whether the platform is secure +* `CdmFileIO`: for the CDM to store persistent data +* `ProvisionFetcher`: for Android MediaDrm device provisioning +* `CdmProxy`: (in progress) + +### Adoption + +#### Android + +* `MediaService` in the GPU process (registered in `GpuServiceFactory` with + `GpuMojoMediaClient`) +* `MojoCdm` + `MediaDrmBridge` (CDM) +* `MediaDrmBridge` uses mojo `ProvisionFetcher` service for CDM provisioning +* `MojoAudioDecoder` + `MediaCodecAudioDecoder` +* `MojoVideoDecoder` + `MediaCodecVideoDecoder` (in progress) +* HLS support: + * `MojoRenderer` + `MediaPlayerRenderer` + * NOT using `MediaService`. Instead, `MojoRendererService` is hosted by + `RenderFrameHostImpl`/`MediaInterfaceProxy` in the browser process + directly. + +#### ChromeCast + +* `MediaService` in the Browser process (registered in + `CastContentBrowserClient` with `CastMojoMediaClient`) +* `MojoRenderer` + `CastRenderer` +* `MojoCdm` + `CastCdm` + +#### Desktop (ChromeOS/Linux/Mac/Windows) + +* CdmService + * `CdmService` in the utility process (registered in `UtilityServiceFactory` + with `ContentCdmServiceClient`) + * `MojoCdm` + `CdmAdapter` + Library CDM implementation + * `CdmAdapter` uses various secure auxiliary services +* MediaService (in progress) + * `MediaService` in the GPU process (registered in `GpuServiceFactory` with + `GpuMojoMediaClient`) + * `MojoVideoDecoder` + hardware video decoders such as D3D11VideoDecoder + * Provides `CdmProxy` to the `CdmService` + +## Other Services + +> TODO(xhwang): Add documentation on other mojo services, e.g. remoting, etc. +
diff --git a/mojo/public/interfaces/bindings/tests/BUILD.gn b/mojo/public/interfaces/bindings/tests/BUILD.gn index f4e30620..939c837c 100644 --- a/mojo/public/interfaces/bindings/tests/BUILD.gn +++ b/mojo/public/interfaces/bindings/tests/BUILD.gn
@@ -27,6 +27,7 @@ action_foreach("validation_test_data_list") { testonly = true script = "//mojo/public/tools/bindings/gen_data_files_list.py" + inputs = mojom_generator_sources sources = [ "data/validation", ]
diff --git a/mojo/public/tools/bindings/gen_data_files_list.py b/mojo/public/tools/bindings/gen_data_files_list.py index 47fcbe3..8d40173 100644 --- a/mojo/public/tools/bindings/gen_data_files_list.py +++ b/mojo/public/tools/bindings/gen_data_files_list.py
@@ -12,11 +12,19 @@ will be written to the list. """ -from optparse import OptionParser import os import re import sys +from cStringIO import StringIO +from optparse import OptionParser + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), + "pylib")) + +from mojom.generate.generator import WriteFile + + def main(): parser = OptionParser() parser.add_option('-d', '--directory', help='Read files from DIRECTORY') @@ -28,9 +36,13 @@ (options, _) = parser.parse_args() pattern = re.compile(options.pattern) files = [f for f in os.listdir(options.directory) if pattern.match(f)] - with file(options.output, 'w') as out: - for f in files: - print >> out, f + + stream = StringIO() + for f in files: + print >> stream, f + + WriteFile(stream.getvalue(), options.output) + stream.close() if __name__ == '__main__': sys.exit(main())
diff --git a/mojo/public/tools/bindings/generate_type_mappings.py b/mojo/public/tools/bindings/generate_type_mappings.py index fd0a466..ee55e99 100755 --- a/mojo/public/tools/bindings/generate_type_mappings.py +++ b/mojo/public/tools/bindings/generate_type_mappings.py
@@ -61,7 +61,12 @@ import json import os import re +import sys +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), + "pylib")) + +from mojom.generate.generator import WriteFile def ReadTypemap(path): with open(path) as f: @@ -143,8 +148,8 @@ raise IOError('Missing dependencies: %s' % ', '.join(missing)) for path in params.dependency: typemaps.update(ReadTypemap(path)) - with open(params.output, 'w') as f: - json.dump({'c++': typemaps}, f, indent=2) + + WriteFile(json.dumps({'c++': typemaps}, indent=2), params.output) if __name__ == '__main__':
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni index b7f8bd2..7ff4168 100644 --- a/mojo/public/tools/bindings/mojom.gni +++ b/mojo/public/tools/bindings/mojom.gni
@@ -339,6 +339,7 @@ parser_target_name = "${target_name}__parser" action_foreach(parser_target_name) { script = mojom_generator_script + inputs = mojom_generator_sources sources = invoker.sources outputs = [ "{{source_gen_dir}}/{{source_name_part}}.p", @@ -722,7 +723,7 @@ } action(type_mappings_target_name) { - inputs = _bindings_configuration_files + inputs = _bindings_configuration_files + mojom_generator_sources outputs = [ type_mappings_path, ]
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py index 1880fc0..a7b5a48 100755 --- a/mojo/public/tools/bindings/mojom_bindings_generator.py +++ b/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -40,9 +40,9 @@ from mojom.error import Error import mojom.fileutil as fileutil -from mojom.generate import translate from mojom.generate import template_expander -from mojom.generate.generator import AddComputedData +from mojom.generate import translate +from mojom.generate.generator import AddComputedData, WriteFile from mojom.parse.conditional_features import RemoveDisabledDefinitions from mojom.parse.parser import Parse @@ -267,8 +267,7 @@ fileutil.EnsureDirectoryExists(full_dir) try: - with open(output_file, "wb") as f: - cPickle.dump(ast, f) + WriteFile(cPickle.dumps(ast), output_file) except (IOError, cPickle.PicklingError) as e: print "%s: Error: %s" % (output_file, str(e)) sys.exit(1)
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py index 7fc0ff8..d91fc7f 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
@@ -70,12 +70,18 @@ def WriteFile(contents, full_path): + # If |contents| is same with the file content, we skip updating. + if os.path.isfile(full_path): + with open(full_path, 'rb') as destination_file: + if destination_file.read() == contents: + return + # Make sure the containing directory exists. full_dir = os.path.dirname(full_path) fileutil.EnsureDirectoryExists(full_dir) # Dump the data to disk. - with open(full_path, "w+") as f: + with open(full_path, "wb") as f: f.write(contents) @@ -191,4 +197,3 @@ def GetGlobals(self): """Returns global mappings for the template generation.""" return {} -
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn index 1aad33e..cbc35ea 100644 --- a/net/android/BUILD.gn +++ b/net/android/BUILD.gn
@@ -204,5 +204,4 @@ "//base:base_junit_test_support", "//third_party/hamcrest:hamcrest_java", ] - srcjar_deps = [ "//base:base_build_config_gen" ] }
diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc index 3456ba1..7d4f50b 100644 --- a/net/disk_cache/entry_unittest.cc +++ b/net/disk_cache/entry_unittest.cc
@@ -82,6 +82,7 @@ bool SimpleCacheMakeBadChecksumEntry(const std::string& key, int data_size); bool SimpleCacheThirdStreamFileExists(const char* key); void SyncDoomEntry(const char* key); + void UseAfterBackendDestruction(); }; // This part of the test runs on the background thread. @@ -4139,6 +4140,24 @@ callback.WaitForResult(); } +void DiskCacheEntryTest::UseAfterBackendDestruction() { + disk_cache::Entry* entry = NULL; + ASSERT_THAT(CreateEntry("the first key", &entry), IsOk()); + cache_.reset(); + + const int kSize = 100; + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); + CacheTestFillBuffer(buffer->data(), kSize, false); + + // Do some writes and reads, but don't change the result. We're OK + // with them failing, just not them crashing. + WriteData(entry, 1, 0, buffer.get(), kSize, false); + ReadData(entry, 1, 0, buffer.get(), kSize); + WriteSparseData(entry, 20000, buffer.get(), kSize); + + entry->Close(); +} + // Check that a newly-created entry with no third-stream writes omits the // third stream file. TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream1) { @@ -4797,6 +4816,26 @@ entry->Close(); } +TEST_F(DiskCacheEntryTest, UseAfterBackendDestruction) { + // InitCache uses the kNoRandom flag that check-fails on the tested scenario. + CreateBackend(0); + DisableIntegrityCheck(); + UseAfterBackendDestruction(); +} + +TEST_F(DiskCacheEntryTest, SimpleUseAfterBackendDestruction) { + SetSimpleCacheMode(); + InitCache(); + UseAfterBackendDestruction(); +} + +TEST_F(DiskCacheEntryTest, MemoryOnlyUseAfterBackendDestruction) { + // https://crbug.com/741620 + SetMemoryOnlyMode(); + InitCache(); + UseAfterBackendDestruction(); +} + class DiskCacheSimplePrefetchTest : public DiskCacheEntryTest { public: DiskCacheSimplePrefetchTest()
diff --git a/net/disk_cache/memory/mem_backend_impl.cc b/net/disk_cache/memory/mem_backend_impl.cc index f906150..865d19c 100644 --- a/net/disk_cache/memory/mem_backend_impl.cc +++ b/net/disk_cache/memory/mem_backend_impl.cc
@@ -50,7 +50,6 @@ DCHECK(CheckLRUListOrder(lru_list_)); while (!entries_.empty()) entries_.begin()->second->Doom(); - DCHECK_EQ(0, current_size_); if (!post_cleanup_callback_.is_null()) base::SequencedTaskRunnerHandle::Get()->PostTask( @@ -175,7 +174,8 @@ if (!did_insert) return net::ERR_FAILED; - MemEntryImpl* cache_entry = new MemEntryImpl(this, key, net_log_); + MemEntryImpl* cache_entry = + new MemEntryImpl(weak_factory_.GetWeakPtr(), key, net_log_); create_result.first->second = cache_entry; *entry = cache_entry; return net::OK;
diff --git a/net/disk_cache/memory/mem_entry_impl.cc b/net/disk_cache/memory/mem_entry_impl.cc index 95f43db9..1774168 100644 --- a/net/disk_cache/memory/mem_entry_impl.cc +++ b/net/disk_cache/memory/mem_entry_impl.cc
@@ -87,7 +87,7 @@ } // namespace -MemEntryImpl::MemEntryImpl(MemBackendImpl* backend, +MemEntryImpl::MemEntryImpl(base::WeakPtr<MemBackendImpl> backend, const std::string& key, net::NetLog* net_log) : MemEntryImpl(backend, @@ -101,7 +101,7 @@ backend_->ModifyStorageSize(GetStorageSize()); } -MemEntryImpl::MemEntryImpl(MemBackendImpl* backend, +MemEntryImpl::MemEntryImpl(base::WeakPtr<MemBackendImpl> backend, int child_id, MemEntryImpl* parent, net::NetLog* net_log) @@ -136,6 +136,7 @@ } void MemEntryImpl::UpdateStateOnUse(EntryModified modified_enum) { + // !doomed_ implies backend_ != null as ~MemBackendImpl dooms everything. if (!doomed_) backend_->OnEntryUpdated(this); @@ -145,6 +146,7 @@ } void MemEntryImpl::Doom() { + // !doomed_ implies backend_ != null as ~MemBackendImpl dooms everything. if (!doomed_) { doomed_ = true; backend_->OnEntryDoomed(this); @@ -280,7 +282,7 @@ // ------------------------------------------------------------------------ -MemEntryImpl::MemEntryImpl(MemBackendImpl* backend, +MemEntryImpl::MemEntryImpl(base::WeakPtr<MemBackendImpl> backend, const ::std::string& key, int child_id, MemEntryImpl* parent, @@ -302,7 +304,8 @@ } MemEntryImpl::~MemEntryImpl() { - backend_->ModifyStorageSize(-GetStorageSize()); + if (backend_) + backend_->ModifyStorageSize(-GetStorageSize()); if (type() == PARENT_ENTRY) { if (children_) { @@ -345,6 +348,12 @@ int MemEntryImpl::InternalWriteData(int index, int offset, IOBuffer* buf, int buf_len, bool truncate) { DCHECK(type() == PARENT_ENTRY || index == kSparseData); + if (!backend_) { + // We have to fail writes after the backend is destroyed since we can't + // ensure we wouldn't use too much memory if it's gone. + RecordWriteResult(WRITE_RESULT_EXCEEDED_CACHE_STORAGE_SIZE); + return net::ERR_INSUFFICIENT_RESOURCES; + } if (index < 0 || index >= kNumStreams) { RecordWriteResult(WRITE_RESULT_INVALID_ARGUMENT); @@ -459,6 +468,11 @@ if (!InitSparseInfo()) return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; + // We can't generally do this without the backend since we need it to create + // child entries. + if (!backend_) + return net::ERR_FAILED; + if (offset < 0 || buf_len < 0) return net::ERR_INVALID_ARGUMENT;
diff --git a/net/disk_cache/memory/mem_entry_impl.h b/net/disk_cache/memory/mem_entry_impl.h index 33ffbdb4..728bec0 100644 --- a/net/disk_cache/memory/mem_entry_impl.h +++ b/net/disk_cache/memory/mem_entry_impl.h
@@ -15,6 +15,7 @@ #include "base/containers/linked_list.h" #include "base/gtest_prod_util.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/trace_event/memory_usage_estimator.h" #include "net/base/interval.h" @@ -73,12 +74,12 @@ }; // Constructor for parent entries. - MemEntryImpl(MemBackendImpl* backend, + MemEntryImpl(base::WeakPtr<MemBackendImpl> backend, const std::string& key, net::NetLog* net_log); // Constructor for child entries. - MemEntryImpl(MemBackendImpl* backend, + MemEntryImpl(base::WeakPtr<MemBackendImpl> backend, int child_id, MemEntryImpl* parent, net::NetLog* net_log); @@ -135,7 +136,7 @@ size_t EstimateMemoryUsage() const; private: - MemEntryImpl(MemBackendImpl* backend, + MemEntryImpl(base::WeakPtr<MemBackendImpl> backend, const std::string& key, int child_id, MemEntryImpl* parent, @@ -185,7 +186,7 @@ base::Time last_modified_; base::Time last_used_; - MemBackendImpl* backend_; // Back pointer to the cache. + base::WeakPtr<MemBackendImpl> backend_; // Back pointer to the cache. bool doomed_; // True if this entry was removed from the cache. net::NetLogWithSource net_log_;
diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc index f1660ca6..0613f642 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.cc +++ b/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -902,11 +902,6 @@ CloseSparseFile(); } - if (files_created_) { - const int stream2_file_index = GetFileIndexFromStreamIndex(2); - SIMPLE_CACHE_UMA(BOOLEAN, "EntryCreatedAndStream2Omitted", cache_type_, - empty_file_omitted_[stream2_file_index]); - } SIMPLE_CACHE_UMA(TIMES, "DiskCloseLatency", cache_type_, close_time.Elapsed()); RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS); @@ -1103,8 +1098,6 @@ "SyncOpenEntryAge", cache_type_, entry_age.InHours(), 1, 1000, 50); - files_created_ = false; - return true; } @@ -1142,8 +1135,6 @@ for (int i = 0; i < kSimpleEntryNormalFileCount; ++i) out_entry_stat->set_data_size(i, 0); - files_created_ = true; - return true; }
diff --git a/net/disk_cache/simple/simple_synchronous_entry.h b/net/disk_cache/simple/simple_synchronous_entry.h index ad53650..709a016e 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.h +++ b/net/disk_cache/simple/simple_synchronous_entry.h
@@ -471,10 +471,6 @@ // Offset of the end of the sparse file (where the next sparse range will be // written). int64_t sparse_tail_offset_; - - // True if the entry was created, or false if it was opened. Used to log - // SimpleCache.*.EntryCreatedWithStream2Omitted only for created entries. - bool files_created_; }; } // namespace disk_cache
diff --git a/net/dns/mojo_host_struct_traits.cc b/net/dns/mojo_host_struct_traits.cc index 94afcd6..27332de 100644 --- a/net/dns/mojo_host_struct_traits.cc +++ b/net/dns/mojo_host_struct_traits.cc
@@ -9,7 +9,6 @@ #include "base/memory/ptr_util.h" #include "net/base/address_list.h" #include "net/interfaces/address_family_mojom_traits.h" -#include "net/interfaces/ip_endpoint_struct_traits.h" namespace mojo { @@ -34,11 +33,4 @@ return true; } -// static -bool StructTraits<net::interfaces::AddressListDataView, net::AddressList>::Read( - net::interfaces::AddressListDataView data, - net::AddressList* out) { - return data.ReadAddresses(&out->endpoints()); -} - } // namespace mojo
diff --git a/net/dns/mojo_host_struct_traits.h b/net/dns/mojo_host_struct_traits.h index f39b844c..ea72da1 100644 --- a/net/dns/mojo_host_struct_traits.h +++ b/net/dns/mojo_host_struct_traits.h
@@ -41,16 +41,6 @@ std::unique_ptr<net::HostResolver::RequestInfo>* output); }; -template <> -struct StructTraits<net::interfaces::AddressListDataView, net::AddressList> { - static std::vector<net::IPEndPoint> addresses(const net::AddressList& obj) { - return obj.endpoints(); - } - - static bool Read(net::interfaces::AddressListDataView data, - net::AddressList* out); -}; - } // namespace mojo #endif // NET_DNS_MOJO_HOST_STRUCT_TRAITS_H_
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc index 35993f3..106f59e 100644 --- a/net/http/http_response_info.cc +++ b/net/http/http_response_info.cc
@@ -387,6 +387,7 @@ case CONNECTION_INFO_QUIC_41: case CONNECTION_INFO_QUIC_42: case CONNECTION_INFO_QUIC_43: + case CONNECTION_INFO_QUIC_99: return true; case NUM_OF_CONNECTION_INFOS: NOTREACHED(); @@ -443,6 +444,8 @@ return "http/2+quic/42"; case CONNECTION_INFO_QUIC_43: return "http/2+quic/43"; + case CONNECTION_INFO_QUIC_99: + return "http/2+quic/99"; case CONNECTION_INFO_HTTP0_9: return "http/0.9"; case CONNECTION_INFO_HTTP1_0:
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h index 36e5f12..40057b49 100644 --- a/net/http/http_response_info.h +++ b/net/http/http_response_info.h
@@ -55,6 +55,7 @@ CONNECTION_INFO_QUIC_41 = 19, CONNECTION_INFO_QUIC_42 = 20, CONNECTION_INFO_QUIC_43 = 21, + CONNECTION_INFO_QUIC_99 = 22, NUM_OF_CONNECTION_INFOS, };
diff --git a/net/interfaces/BUILD.gn b/net/interfaces/BUILD.gn index 728e697..e6684efc 100644 --- a/net/interfaces/BUILD.gn +++ b/net/interfaces/BUILD.gn
@@ -7,6 +7,7 @@ mojom("interfaces") { sources = [ "address_family.mojom", + "address_list.mojom", "host_resolver_service.mojom", "ip_address.mojom", "ip_endpoint.mojom",
diff --git a/net/interfaces/address_list.mojom b/net/interfaces/address_list.mojom new file mode 100644 index 0000000..8ad6523 --- /dev/null +++ b/net/interfaces/address_list.mojom
@@ -0,0 +1,12 @@ +// Copyright 2018 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 net.interfaces; + +import "net/interfaces/ip_endpoint.mojom"; + +// Mirror of net::AddressList. +struct AddressList { + array<IPEndPoint> addresses; +};
diff --git a/net/interfaces/address_list.typemap b/net/interfaces/address_list.typemap new file mode 100644 index 0000000..1c53362 --- /dev/null +++ b/net/interfaces/address_list.typemap
@@ -0,0 +1,14 @@ +# Copyright 2018 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. + +mojom = "//net/interfaces/address_list.mojom" +public_headers = [ "//net/base/address_list.h" ] +traits_headers = [ "//net/interfaces/address_list_mojom_traits.h" ] +sources = [ + "//net/interfaces/address_list_mojom_traits.cc", +] +type_mappings = [ "net.interfaces.AddressList=net::AddressList" ] +public_deps = [ + "//net", +]
diff --git a/net/interfaces/address_list_mojom_traits.cc b/net/interfaces/address_list_mojom_traits.cc new file mode 100644 index 0000000..9ae7c24 --- /dev/null +++ b/net/interfaces/address_list_mojom_traits.cc
@@ -0,0 +1,19 @@ +// Copyright 2018 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 "net/interfaces/address_list_mojom_traits.h" + +#include "net/base/address_list.h" +#include "net/interfaces/ip_endpoint_struct_traits.h" + +namespace mojo { + +// static +bool StructTraits<net::interfaces::AddressListDataView, net::AddressList>::Read( + net::interfaces::AddressListDataView data, + net::AddressList* out) { + return data.ReadAddresses(&out->endpoints()); +} + +} // namespace mojo
diff --git a/net/interfaces/address_list_mojom_traits.h b/net/interfaces/address_list_mojom_traits.h new file mode 100644 index 0000000..3f38d82d --- /dev/null +++ b/net/interfaces/address_list_mojom_traits.h
@@ -0,0 +1,28 @@ +// Copyright 2018 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 NET_INTERFACES_ADDRESS_LIST_MOJOM_TRAITS_H_ +#define NET_INTERFACES_ADDRESS_LIST_MOJOM_TRAITS_H_ + +#include <vector> + +#include "mojo/public/cpp/bindings/struct_traits.h" +#include "net/interfaces/address_list.mojom.h" + +namespace mojo { + +template <> +struct StructTraits<net::interfaces::AddressListDataView, net::AddressList> { + static const std::vector<net::IPEndPoint>& addresses( + const net::AddressList& obj) { + return obj.endpoints(); + } + + static bool Read(net::interfaces::AddressListDataView data, + net::AddressList* out); +}; + +} // namespace mojo + +#endif // NET_INTERFACES_ADDRESS_LIST_MOJOM_TRAITS_H_
diff --git a/net/interfaces/host_resolver.typemap b/net/interfaces/host_resolver.typemap index c0f559c..ada34d2 100644 --- a/net/interfaces/host_resolver.typemap +++ b/net/interfaces/host_resolver.typemap
@@ -8,10 +8,7 @@ sources = [ "//net/dns/mojo_host_struct_traits.cc", ] -type_mappings = [ - "net.interfaces.HostResolverRequestInfo=std::unique_ptr<net::HostResolver::RequestInfo>[move_only]", - "net.interfaces.AddressList=net::AddressList", -] +type_mappings = [ "net.interfaces.HostResolverRequestInfo=std::unique_ptr<net::HostResolver::RequestInfo>[move_only]" ] public_deps = [ "//net", ]
diff --git a/net/interfaces/host_resolver_service.mojom b/net/interfaces/host_resolver_service.mojom index 4a5e030..8600a2dc 100644 --- a/net/interfaces/host_resolver_service.mojom +++ b/net/interfaces/host_resolver_service.mojom
@@ -12,8 +12,8 @@ // TODO(amistry): Resolve the conflict between these two sets of definitions. module net.interfaces; -import "net/interfaces/ip_endpoint.mojom"; import "net/interfaces/address_family.mojom"; +import "net/interfaces/address_list.mojom"; // Mirror of net::HostResolver::RequestInfo. struct HostResolverRequestInfo { @@ -23,11 +23,6 @@ bool is_my_ip_address; }; -// Mirror of net::AddressList. -struct AddressList { - array<IPEndPoint> addresses; -}; - interface HostResolverRequestClient { // |error| is a value in net::Error. ReportResult(int32 error, AddressList result);
diff --git a/net/interfaces/typemaps.gni b/net/interfaces/typemaps.gni index b36db710..7cf8bc7b 100644 --- a/net/interfaces/typemaps.gni +++ b/net/interfaces/typemaps.gni
@@ -4,6 +4,7 @@ typemaps = [ "//net/interfaces/address_family.typemap", + "//net/interfaces/address_list.typemap", "//net/interfaces/host_resolver.typemap", "//net/interfaces/ip_address.typemap", "//net/interfaces/ip_endpoint.typemap",
diff --git a/net/quic/chromium/quic_http_stream.cc b/net/quic/chromium/quic_http_stream.cc index 547b9b93..6774ec8 100644 --- a/net/quic/chromium/quic_http_stream.cc +++ b/net/quic/chromium/quic_http_stream.cc
@@ -93,6 +93,8 @@ return HttpResponseInfo::CONNECTION_INFO_QUIC_42; case QUIC_VERSION_43: return HttpResponseInfo::CONNECTION_INFO_QUIC_43; + case QUIC_VERSION_99: + return HttpResponseInfo::CONNECTION_INFO_QUIC_99; } NOTREACHED(); return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION;
diff --git a/net/quic/core/congestion_control/bandwidth_sampler.cc b/net/quic/core/congestion_control/bandwidth_sampler.cc index 47b64ef..d73dd92 100644 --- a/net/quic/core/congestion_control/bandwidth_sampler.cc +++ b/net/quic/core/congestion_control/bandwidth_sampler.cc
@@ -119,8 +119,10 @@ // always larger than the time of the previous packet, otherwise division by // zero or integer underflow can occur. if (ack_time <= sent_packet.last_acked_packet_ack_time) { - QUIC_BUG << "Time of the previously acked packet is larger than the time " - "of the current packet."; + QUIC_BUG << "Time of the previously acked packet:" + << sent_packet.last_acked_packet_ack_time.ToDebuggingValue() + << " is larger than the ack time of the current packet:" + << ack_time.ToDebuggingValue(); return BandwidthSample(); } QuicBandwidth ack_rate = QuicBandwidth::FromBytesAndTimeDelta(
diff --git a/net/quic/core/congestion_control/bbr_sender.cc b/net/quic/core/congestion_control/bbr_sender.cc index 927ef1e..3013c16d 100644 --- a/net/quic/core/congestion_control/bbr_sender.cc +++ b/net/quic/core/congestion_control/bbr_sender.cc
@@ -346,9 +346,7 @@ } QuicTime::Delta BbrSender::GetMinRtt() const { - return !min_rtt_.IsZero() - ? min_rtt_ - : QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us()); + return !min_rtt_.IsZero() ? min_rtt_ : rtt_stats_->initial_rtt(); } QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const {
diff --git a/net/quic/core/congestion_control/bbr_sender_test.cc b/net/quic/core/congestion_control/bbr_sender_test.cc index a229e8a..f035ad0 100644 --- a/net/quic/core/congestion_control/bbr_sender_test.cc +++ b/net/quic/core/congestion_control/bbr_sender_test.cc
@@ -270,8 +270,7 @@ // Verify that pacing rate is based on the initial RTT. QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta( - 2.885 * kDefaultWindowTCP, - QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us())); + 2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt()); ExpectApproxEq(expected_pacing_rate.ToBitsPerSecond(), sender_->PacingRate(0).ToBitsPerSecond(), 0.01f); @@ -862,7 +861,7 @@ QuicBandwidth initial_rate = QuicBandwidth::FromBytesAndTimeDelta( kInitialCongestionWindowPackets * kDefaultTCPMSS, - QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us())); + rtt_stats_->initial_rtt()); EXPECT_GE(sender_->PacingRate(0), initial_rate); // Send a packet.
diff --git a/net/quic/core/congestion_control/rtt_stats.cc b/net/quic/core/congestion_control/rtt_stats.cc index 00de79d5..6999598 100644 --- a/net/quic/core/congestion_control/rtt_stats.cc +++ b/net/quic/core/congestion_control/rtt_stats.cc
@@ -29,7 +29,7 @@ smoothed_rtt_(QuicTime::Delta::Zero()), previous_srtt_(QuicTime::Delta::Zero()), mean_deviation_(QuicTime::Delta::Zero()), - initial_rtt_us_(kInitialRttMs * kNumMicrosPerMilli), + initial_rtt_(QuicTime::Delta::FromMilliseconds(kInitialRttMs)), max_ack_delay_(QuicTime::Delta::Zero()), ignore_max_ack_delay_(false) {} @@ -101,7 +101,7 @@ min_rtt_ = QuicTime::Delta::Zero(); smoothed_rtt_ = QuicTime::Delta::Zero(); mean_deviation_ = QuicTime::Delta::Zero(); - initial_rtt_us_ = kInitialRttMs * kNumMicrosPerMilli; + initial_rtt_ = QuicTime::Delta::FromMilliseconds(kInitialRttMs); max_ack_delay_ = QuicTime::Delta::Zero(); }
diff --git a/net/quic/core/congestion_control/rtt_stats.h b/net/quic/core/congestion_control/rtt_stats.h index 70d6dda..025e38d 100644 --- a/net/quic/core/congestion_control/rtt_stats.h +++ b/net/quic/core/congestion_control/rtt_stats.h
@@ -47,15 +47,19 @@ // Returns the EWMA smoothed RTT prior to the most recent RTT sample. QuicTime::Delta previous_srtt() const { return previous_srtt_; } - int64_t initial_rtt_us() const { return initial_rtt_us_; } + QuicTime::Delta initial_rtt() const { return initial_rtt_; } + + QuicTime::Delta SmoothedOrInitialRtt() const { + return smoothed_rtt_.IsZero() ? initial_rtt_ : smoothed_rtt_; + } // Sets an initial RTT to be used for SmoothedRtt before any RTT updates. - void set_initial_rtt_us(int64_t initial_rtt_us) { - if (initial_rtt_us <= 0) { + void set_initial_rtt(QuicTime::Delta initial_rtt) { + if (initial_rtt.ToMicroseconds() <= 0) { QUIC_BUG << "Attempt to set initial rtt to <= 0."; return; } - initial_rtt_us_ = initial_rtt_us; + initial_rtt_ = initial_rtt; } // The most recent rtt measurement. @@ -92,7 +96,7 @@ // Approximation of standard deviation, the error is roughly 1.25 times // larger than the standard deviation, for a normally distributed signal. QuicTime::Delta mean_deviation_; - int64_t initial_rtt_us_; + QuicTime::Delta initial_rtt_; // The maximum ack delay observed over the connection after excluding ack // delays that were too large to be included in an RTT measurement. QuicTime::Delta max_ack_delay_;
diff --git a/net/quic/core/congestion_control/rtt_stats_test.cc b/net/quic/core/congestion_control/rtt_stats_test.cc index aa57109..1e026ba 100644 --- a/net/quic/core/congestion_control/rtt_stats_test.cc +++ b/net/quic/core/congestion_control/rtt_stats_test.cc
@@ -24,7 +24,7 @@ }; TEST_F(RttStatsTest, DefaultsBeforeUpdate) { - EXPECT_LT(0u, rtt_stats_.initial_rtt_us()); + EXPECT_LT(QuicTime::Delta::Zero(), rtt_stats_.initial_rtt()); EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt()); EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt()); }
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc index 1cb6e772..467b69a 100644 --- a/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc +++ b/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -206,10 +206,7 @@ // We pace at twice the rate of the underlying sender's bandwidth estimate // during slow start and 1.25x during congestion avoidance to ensure pacing // doesn't prevent us from filling the window. - QuicTime::Delta srtt = rtt_stats_->smoothed_rtt(); - if (srtt.IsZero()) { - srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us()); - } + QuicTime::Delta srtt = rtt_stats_->SmoothedOrInitialRtt(); const QuicBandwidth bandwidth = QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt); return bandwidth * (InSlowStart() ? 2 : (no_prr_ && InRecovery() ? 1 : 1.25));
diff --git a/net/quic/core/crypto/transport_parameters.cc b/net/quic/core/crypto/transport_parameters.cc index 1b118b7..9dad023e 100644 --- a/net/quic/core/crypto/transport_parameters.cc +++ b/net/quic/core/crypto/transport_parameters.cc
@@ -127,20 +127,22 @@ } } + CBB initial_max_stream_id_bidi_param; if (in.initial_max_stream_id_bidi.present) { - CBB initial_max_stream_id_param; if (!CBB_add_u16(¶ms, kInitialMaxStreamIdBidi) || - !CBB_add_u16_length_prefixed(¶ms, &initial_max_stream_id_param) || - !CBB_add_u32(&initial_max_stream_id_param, + !CBB_add_u16_length_prefixed(¶ms, + &initial_max_stream_id_bidi_param) || + !CBB_add_u32(&initial_max_stream_id_bidi_param, in.initial_max_stream_id_bidi.value)) { return false; } } + CBB initial_max_stream_id_uni_param; if (in.initial_max_stream_id_uni.present) { - CBB initial_max_stream_id_param; if (!CBB_add_u16(¶ms, kInitialMaxStreamIdUni) || - !CBB_add_u16_length_prefixed(¶ms, &initial_max_stream_id_param) || - !CBB_add_u32(&initial_max_stream_id_param, + !CBB_add_u16_length_prefixed(¶ms, + &initial_max_stream_id_uni_param) || + !CBB_add_u32(&initial_max_stream_id_uni_param, in.initial_max_stream_id_uni.value)) { return false; } @@ -150,19 +152,19 @@ return false; } } + CBB max_packet_size_param; if (in.max_packet_size.present) { - CBB max_packet_size_param; if (!CBB_add_u16(¶ms, kMaxPacketSize) || !CBB_add_u16_length_prefixed(¶ms, &max_packet_size_param) || !CBB_add_u16(&max_packet_size_param, in.max_packet_size.value)) { return false; } } + CBB ack_delay_exponent_param; if (in.ack_delay_exponent.present) { - CBB max_packet_size_param; - if (!CBB_add_u16(¶ms, kMaxPacketSize) || - !CBB_add_u16_length_prefixed(¶ms, &max_packet_size_param) || - !CBB_add_u8(&max_packet_size_param, in.ack_delay_exponent.value)) { + if (!CBB_add_u16(¶ms, kAckDelayExponent) || + !CBB_add_u16_length_prefixed(¶ms, &ack_delay_exponent_param) || + !CBB_add_u8(&ack_delay_exponent_param, in.ack_delay_exponent.value)) { return false; } } @@ -260,12 +262,8 @@ if (CBS_len(&value) == 0) { return false; } - out->stateless_reset_token.resize(CBS_len(&value)); - if (!CBS_copy_bytes(&value, out->stateless_reset_token.data(), - CBS_len(&value)) || - CBS_len(&value) != 0) { - return false; - } + out->stateless_reset_token.assign(CBS_data(&value), + CBS_data(&value) + CBS_len(&value)); break; case kAckDelayExponent: if (!CBS_get_u8(&value, &out->ack_delay_exponent.value) ||
diff --git a/net/quic/core/crypto/transport_parameters_test.cc b/net/quic/core/crypto/transport_parameters_test.cc index 2e7e987..a556dbf5 100644 --- a/net/quic/core/crypto/transport_parameters_test.cc +++ b/net/quic/core/crypto/transport_parameters_test.cc
@@ -19,6 +19,14 @@ orig_params.initial_max_stream_data = 12; orig_params.initial_max_data = 34; orig_params.idle_timeout = 56; + orig_params.initial_max_stream_id_bidi.present = true; + orig_params.initial_max_stream_id_bidi.value = 2000; + orig_params.initial_max_stream_id_uni.present = true; + orig_params.initial_max_stream_id_uni.value = 3000; + orig_params.max_packet_size.present = true; + orig_params.max_packet_size.value = 9001; + orig_params.ack_delay_exponent.present = true; + orig_params.ack_delay_exponent.value = 10; orig_params.version = 0xff000005; std::vector<uint8_t> serialized; @@ -33,6 +41,18 @@ EXPECT_EQ(new_params.initial_max_data, orig_params.initial_max_data); EXPECT_EQ(new_params.idle_timeout, orig_params.idle_timeout); EXPECT_EQ(new_params.version, orig_params.version); + EXPECT_TRUE(new_params.initial_max_stream_id_bidi.present); + EXPECT_EQ(new_params.initial_max_stream_id_bidi.value, + orig_params.initial_max_stream_id_bidi.value); + EXPECT_TRUE(new_params.initial_max_stream_id_uni.present); + EXPECT_EQ(new_params.initial_max_stream_id_uni.value, + orig_params.initial_max_stream_id_uni.value); + EXPECT_TRUE(new_params.max_packet_size.present); + EXPECT_EQ(new_params.max_packet_size.value, + orig_params.max_packet_size.value); + EXPECT_TRUE(new_params.ack_delay_exponent.present); + EXPECT_EQ(new_params.ack_delay_exponent.value, + orig_params.ack_delay_exponent.value); } TEST_F(TransportParametersTest, RoundTripServer) {
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc index 8a67fa97..3fdc2b6 100644 --- a/net/quic/core/quic_connection.cc +++ b/net/quic/core/quic_connection.cc
@@ -400,6 +400,11 @@ sent_packet_manager_.SetMaxPacingRate(max_pacing_rate); } +void QuicConnection::AdjustNetworkParameters(QuicBandwidth bandwidth, + QuicTime::Delta rtt) { + sent_packet_manager_.AdjustNetworkParameters(bandwidth, rtt); +} + QuicBandwidth QuicConnection::MaxPacingRate() const { return sent_packet_manager_.MaxPacingRate(); } @@ -656,9 +661,8 @@ current_packet_content_ = NO_FRAMES_RECEIVED; current_peer_migration_type_ = NO_CHANGE; } - PeerAddressChangeType peer_migration_type = - QuicUtils::DetermineAddressChangeType(peer_address_, - last_packet_source_address_); + AddressChangeType peer_migration_type = QuicUtils::DetermineAddressChangeType( + peer_address_, last_packet_source_address_); // Initiate connection migration if a non-reordered packet is received from a // new address. if (header.packet_number > received_packet_manager_.GetLargestObserved() && @@ -1321,15 +1325,11 @@ QuicTime::Delta min_rtt = rtt_stats->min_rtt(); if (min_rtt.IsZero()) { // If min RTT has not been set, use initial RTT instead. - min_rtt = QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); + min_rtt = rtt_stats->initial_rtt(); } stats_.min_rtt_us = min_rtt.ToMicroseconds(); - QuicTime::Delta srtt = rtt_stats->smoothed_rtt(); - if (srtt.IsZero()) { - // If SRTT has not been set, use initial RTT instead. - srtt = QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); - } + QuicTime::Delta srtt = rtt_stats->SmoothedOrInitialRtt(); stats_.srtt_us = srtt.ToMicroseconds(); stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate(); @@ -1918,8 +1918,7 @@ // Uses the connection's smoothed RTT. If zero, uses initial_rtt. QuicTime::Delta rtt = sent_packet_manager_.GetRttStats()->smoothed_rtt(); if (rtt.IsZero()) { - rtt = QuicTime::Delta::FromMicroseconds( - sent_packet_manager_.GetRttStats()->initial_rtt_us()); + rtt = sent_packet_manager_.GetRttStats()->initial_rtt(); } if (debug_visitor_ != nullptr) { @@ -2575,6 +2574,7 @@ packet_generator_.SerializeConnectivityProbingPacket()); DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA); + const QuicTime packet_send_time = clock_->Now(); WriteResult result = probing_writer->WritePacket( probing_packet->encrypted_buffer, probing_packet->encrypted_length, self_address().host(), peer_address, per_packet_options_); @@ -2589,7 +2589,7 @@ // write the same as a packet loss. sent_packet_manager_.OnPacketSent( probing_packet.get(), probing_packet->original_packet_number, - clock_->Now(), probing_packet->transmission_type, + packet_send_time, probing_packet->transmission_type, NO_RETRANSMITTABLE_DATA); if (result.status == WRITE_STATUS_BLOCKED) { @@ -2638,8 +2638,7 @@ // from a packet with sequence number > the one that triggered the previous // migration. This should happen even if a migration is underway, since the // most recent migration is the one that we should pay attention to. -void QuicConnection::StartPeerMigration( - PeerAddressChangeType peer_migration_type) { +void QuicConnection::StartPeerMigration(AddressChangeType peer_migration_type) { // TODO(fayang): Currently, all peer address change type are allowed. Need to // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to // determine whether |type| is allowed. @@ -2663,8 +2662,7 @@ OnConnectionMigration(peer_migration_type); } -void QuicConnection::OnConnectionMigration( - PeerAddressChangeType addr_change_type) { +void QuicConnection::OnConnectionMigration(AddressChangeType addr_change_type) { visitor_->OnConnectionMigration(addr_change_type); sent_packet_manager_.OnConnectionMigration(addr_change_type); }
diff --git a/net/quic/core/quic_connection.h b/net/quic/core/quic_connection.h index 879e6a27..4897548 100644 --- a/net/quic/core/quic_connection.h +++ b/net/quic/core/quic_connection.h
@@ -136,7 +136,7 @@ virtual void OnCongestionWindowChange(QuicTime now) = 0; // Called when the connection receives a packet from a migrated client. - virtual void OnConnectionMigration(PeerAddressChangeType type) = 0; + virtual void OnConnectionMigration(AddressChangeType type) = 0; // Called when the peer seems unreachable over the current path. virtual void OnPathDegrading() = 0; @@ -350,6 +350,10 @@ // Called by the Session when a max pacing rate for the connection is needed. virtual void SetMaxPacingRate(QuicBandwidth max_pacing_rate); + // Allows the client to adjust network parameters based on external + // information. + void AdjustNetworkParameters(QuicBandwidth bandwidth, QuicTime::Delta rtt); + // Returns the max pacing rate for the connection. QuicBandwidth MaxPacingRate() const; @@ -747,7 +751,7 @@ // Called after a packet is received from a new peer address and is decrypted. // Starts validation of peer's address change. - virtual void StartPeerMigration(PeerAddressChangeType peer_migration_type); + virtual void StartPeerMigration(AddressChangeType peer_migration_type); // Called when a peer address migration is validated. virtual void OnPeerMigrationValidated(); @@ -766,7 +770,7 @@ per_packet_options_ = options; } - PeerAddressChangeType active_peer_migration_type() { + AddressChangeType active_peer_migration_type() { return active_peer_migration_type_; } @@ -788,7 +792,7 @@ // Notify various components(SendPacketManager, Session etc.) that this // connection has been migrated. - void OnConnectionMigration(PeerAddressChangeType addr_change_type); + void OnConnectionMigration(AddressChangeType addr_change_type); private: friend class test::QuicConnectionPeer; @@ -835,7 +839,7 @@ // Deletes and clears any queued packets. void ClearQueuedPackets(); - // Closes the connection if the sent packet manager are tracking too many + // Closes the connection if the sent packet manager is tracking too many // outstanding packets. void CloseIfTooManyOutstandingSentPackets(); @@ -920,7 +924,7 @@ // Caches the current peer migration type if a peer migration might be // initiated. As soon as the current packet is confirmed not a connectivity // probe, peer migration will start. - PeerAddressChangeType current_peer_migration_type_; + AddressChangeType current_peer_migration_type_; QuicConnectionHelperInterface* helper_; // Not owned. QuicAlarmFactory* alarm_factory_; // Not owned. PerPacketOptions* per_packet_options_; // Not owned. @@ -940,7 +944,7 @@ // Records change type when the peer initiates migration to a new peer // address. Reset to NO_CHANGE after peer migration is validated. - PeerAddressChangeType active_peer_migration_type_; + AddressChangeType active_peer_migration_type_; // Records highest sent packet number when peer migration is started. QuicPacketNumber highest_packet_sent_before_peer_migration_;
diff --git a/net/quic/core/quic_connection_test.cc b/net/quic/core/quic_connection_test.cc index cc841c3e..d8bc82b 100644 --- a/net/quic/core/quic_connection_test.cc +++ b/net/quic/core/quic_connection_test.cc
@@ -1959,17 +1959,6 @@ ProcessAckPacket(&frame1); } -TEST_P(QuicConnectionTest, TooManyReceivedPackets) { - EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); - EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber()); - // Miss 99 of every 100 packets for 5500 packets. - for (QuicPacketNumber i = 1; i < kMaxTrackedPackets + 500; i += 100) { - ProcessPacket(i); - if (!connection_.connected()) { - break; - } - } -} TEST_P(QuicConnectionTest, LargestObservedLower) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); @@ -3679,7 +3668,7 @@ EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline()); // Now send more data. This will not move the timeout because - // no data has been recieved since the previous write. + // no data has been received since the previous write. clock_.AdvanceTime(five_ms); SendStreamDataToPeer(kClientDataStreamId1, "foo", 3, FIN, nullptr); EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline()); @@ -3816,7 +3805,7 @@ EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline()); // Now send more data. This will not move the timeout because - // no data has been recieved since the previous write. + // no data has been received since the previous write. clock_.AdvanceTime(five_ms); SendStreamDataToPeer(kClientDataStreamId1, "foo", 3, FIN, nullptr); EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
diff --git a/net/quic/core/quic_flags_list.h b/net/quic/core/quic_flags_list.h index 5311ff0b..81f7a95 100644 --- a/net/quic/core/quic_flags_list.h +++ b/net/quic/core/quic_flags_list.h
@@ -141,7 +141,7 @@ // If true, stream sequencer buffer allows receiving overlapping stream data. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_allow_receiving_overlapping_data, - false) + true) // If true, QuicStreamSendBuffer keeps track of the slice which next write // should get data from if writing new data. @@ -176,3 +176,11 @@ bool, FLAGS_quic_reloadable_flag_quic_close_session_on_too_many_outstanding_sent_packets, false) + +// If true, enable QUIC v99. +QUIC_FLAG(bool, FLAGS_quic_enable_version_99, false) + +// If both this flag and +// gfe2_reloadable_flag_quic_allow_receiving_overlapping_data are +// true, enable QUIC version 42. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_42, false)
diff --git a/net/quic/core/quic_framer.cc b/net/quic/core/quic_framer.cc index 9d69775..3f2eb56 100644 --- a/net/quic/core/quic_framer.cc +++ b/net/quic/core/quic_framer.cc
@@ -143,7 +143,7 @@ uint8_t flags) { switch (flags & PACKET_FLAGS_8BYTE_PACKET) { case PACKET_FLAGS_8BYTE_PACKET: - return version <= QUIC_VERSION_39 ? PACKET_6BYTE_PACKET_NUMBER + return version != QUIC_VERSION_41 ? PACKET_6BYTE_PACKET_NUMBER : PACKET_8BYTE_PACKET_NUMBER; case PACKET_FLAGS_4BYTE_PACKET: return PACKET_4BYTE_PACKET_NUMBER; @@ -255,7 +255,7 @@ // static size_t QuicFramer::GetStreamOffsetSize(QuicTransportVersion version, QuicStreamOffset offset) { - if (version < QUIC_VERSION_41) { + if (version != QUIC_VERSION_41) { // 0 is a special case. if (offset == 0) { return 0; @@ -944,7 +944,7 @@ } else if (packet_number < UINT64_C(1) << (PACKET_4BYTE_PACKET_NUMBER * 8)) { return PACKET_4BYTE_PACKET_NUMBER; } else { - return version <= QUIC_VERSION_39 ? PACKET_6BYTE_PACKET_NUMBER + return version != QUIC_VERSION_41 ? PACKET_6BYTE_PACKET_NUMBER : PACKET_8BYTE_PACKET_NUMBER; } } @@ -1055,7 +1055,7 @@ if (frame_type & kQuicFrameTypeSpecialMask) { // Stream Frame - if ((version_.transport_version < QUIC_VERSION_41 && + if ((version_.transport_version != QUIC_VERSION_41 && (frame_type & kQuicFrameTypeStreamMask_Pre40)) || (version_.transport_version >= QUIC_VERSION_41 && ((frame_type & kQuicFrameTypeStreamMask) == @@ -1074,7 +1074,7 @@ } // Ack Frame - if ((version_.transport_version < QUIC_VERSION_41 && + if ((version_.transport_version != QUIC_VERSION_41 && (frame_type & kQuicFrameTypeAckMask_Pre40)) || (version_.transport_version >= QUIC_VERSION_41 && ((frame_type & kQuicFrameTypeSpecialMask) == @@ -1254,7 +1254,7 @@ uint8_t stream_id_length = 0; uint8_t offset_length = 4; bool has_data_length = true; - if (version_.transport_version < QUIC_VERSION_41) { + if (version_.transport_version != QUIC_VERSION_41) { stream_flags &= ~kQuicFrameTypeStreamMask_Pre40; // Read from right to left: StreamID, Offset, Data Length, Fin. @@ -1328,12 +1328,12 @@ uint8_t frame_type, QuicAckFrame* ack_frame) { bool has_ack_blocks = - ExtractBit(frame_type, version_.transport_version < QUIC_VERSION_41 + ExtractBit(frame_type, version_.transport_version != QUIC_VERSION_41 ? kQuicHasMultipleAckBlocksOffset_Pre40 : kQuicHasMultipleAckBlocksOffset); uint8_t num_ack_blocks = 0; uint8_t num_received_packets = 0; - if (version_.transport_version > QUIC_VERSION_39) { + if (version_.transport_version == QUIC_VERSION_41) { if (has_ack_blocks && !reader->ReadUInt8(&num_ack_blocks)) { set_detailed_error("Unable to read num of ack blocks."); return false; @@ -1375,7 +1375,7 @@ } if (has_ack_blocks) { - if (version_.transport_version <= QUIC_VERSION_39 && + if (version_.transport_version != QUIC_VERSION_41 && !reader->ReadUInt8(&num_ack_blocks)) { set_detailed_error("Unable to read num of ack blocks."); return false; @@ -1441,7 +1441,7 @@ } } - if (version_.transport_version <= QUIC_VERSION_39 && + if (version_.transport_version != QUIC_VERSION_41 && !reader->ReadUInt8(&num_received_packets)) { set_detailed_error("Unable to read num received packets."); return false; @@ -1529,7 +1529,7 @@ return false; } - if (version_.transport_version <= QUIC_VERSION_39) { + if (version_.transport_version != QUIC_VERSION_41) { if (!reader->ReadUInt64(&frame->byte_offset)) { set_detailed_error("Unable to read rst stream sent byte offset."); return false; @@ -1549,7 +1549,7 @@ frame->error_code = static_cast<QuicRstStreamErrorCode>(error_code); - if (version_.transport_version > QUIC_VERSION_39) { + if (version_.transport_version == QUIC_VERSION_41) { if (!reader->ReadUInt64(&frame->byte_offset)) { set_detailed_error("Unable to read rst stream sent byte offset."); return false; @@ -1924,7 +1924,7 @@ if (frame.stream_frame == nullptr) { QUIC_BUG << "Failed to append STREAM frame with no stream_frame."; } - if (version_.transport_version < QUIC_VERSION_41) { + if (version_.transport_version != QUIC_VERSION_41) { // Fin bit. type_byte |= frame.stream_frame->fin ? kQuicStreamFinMask_Pre40 : 0; @@ -2106,7 +2106,7 @@ // Whether there are multiple ack blocks. uint8_t type_byte = 0; SetBit(&type_byte, new_ack_info.num_ack_blocks != 0, - version_.transport_version < QUIC_VERSION_41 + version_.transport_version != QUIC_VERSION_41 ? kQuicHasMultipleAckBlocksOffset_Pre40 : kQuicHasMultipleAckBlocksOffset); @@ -2116,7 +2116,7 @@ SetBits(&type_byte, GetPacketNumberFlags(ack_block_length), kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset); - if (version_.transport_version < QUIC_VERSION_41) { + if (version_.transport_version != QUIC_VERSION_41) { type_byte |= kQuicFrameTypeAckMask_Pre40; } else { type_byte |= kQuicFrameTypeAckMask; @@ -2137,7 +2137,7 @@ num_ack_blocks = std::numeric_limits<uint8_t>::max(); } - if (version_.transport_version > QUIC_VERSION_39) { + if (version_.transport_version == QUIC_VERSION_41) { if (num_ack_blocks > 0 && !writer->WriteBytes(&num_ack_blocks, 1)) { return false; } @@ -2166,7 +2166,7 @@ return false; } - if (version_.transport_version <= QUIC_VERSION_39) { + if (version_.transport_version != QUIC_VERSION_41) { if (num_ack_blocks > 0) { if (!writer->WriteBytes(&num_ack_blocks, 1)) { return false; @@ -2266,7 +2266,7 @@ } uint8_t num_received_packets = frame.received_packet_times.size(); - if (version_.transport_version <= QUIC_VERSION_39) { + if (version_.transport_version != QUIC_VERSION_41) { if (!writer->WriteBytes(&num_received_packets, 1)) { return false; } @@ -2357,7 +2357,7 @@ return false; } - if (version_.transport_version <= QUIC_VERSION_39) { + if (version_.transport_version != QUIC_VERSION_41) { if (!writer->WriteUInt64(frame.byte_offset)) { return false; } @@ -2368,7 +2368,7 @@ return false; } - if (version_.transport_version > QUIC_VERSION_39) { + if (version_.transport_version == QUIC_VERSION_41) { if (!writer->WriteUInt64(frame.byte_offset)) { return false; }
diff --git a/net/quic/core/quic_framer_test.cc b/net/quic/core/quic_framer_test.cc index 3f11cdf..ebbb1e4 100644 --- a/net/quic/core/quic_framer_test.cc +++ b/net/quic/core/quic_framer_test.cc
@@ -1160,7 +1160,7 @@ return; } unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -1280,7 +1280,7 @@ }; PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -1384,7 +1384,7 @@ // clang-format on unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -1490,7 +1490,7 @@ }; PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -1609,7 +1609,7 @@ }; PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -1728,7 +1728,7 @@ }; PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -1856,7 +1856,7 @@ }; PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -1957,7 +1957,7 @@ // clang-format on unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -2081,7 +2081,7 @@ }; PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -2189,7 +2189,7 @@ }; PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -2324,7 +2324,7 @@ // clang-format on PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); @@ -2432,7 +2432,7 @@ // clang-format on PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -2661,7 +2661,7 @@ // clang-format on PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); @@ -2865,7 +2865,7 @@ }; PacketFragments& fragments = - framer_.transport_version() > QUIC_VERSION_39 + framer_.transport_version() == QUIC_VERSION_41 ? packet41 : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -3634,7 +3634,7 @@ ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -3878,7 +3878,7 @@ ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -3966,7 +3966,7 @@ ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -4075,7 +4075,7 @@ }; // clang-format on unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -4166,7 +4166,7 @@ // clang-format on unsigned char* p = packet; size_t packet_size = QUIC_ARRAYSIZE(packet); - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; packet_size = QUIC_ARRAYSIZE(packet41); } else if (framer_.transport_version() > QUIC_VERSION_38) { @@ -4316,7 +4316,7 @@ }; // clang-format on unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -4630,7 +4630,7 @@ }; // clang-format on unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -4778,7 +4778,7 @@ ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -5885,7 +5885,7 @@ EXPECT_CALL(visitor, OnDecryptedPacket(_)); unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39; @@ -6087,7 +6087,7 @@ // clang-format on unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_39) { + if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; } else if (framer_.transport_version() > QUIC_VERSION_38) { p = packet39;
diff --git a/net/quic/core/quic_packet_creator_test.cc b/net/quic/core/quic_packet_creator_test.cc index f7d1100..56bbdd2 100644 --- a/net/quic/core/quic_packet_creator_test.cc +++ b/net/quic/core/quic_packet_creator_test.cc
@@ -721,7 +721,7 @@ QuicPacketCreatorPeer::SetPacketNumber(&creator_, UINT64_C(64) * 256 * 256 * 256 * 256); creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize); - if (GetParam().version.transport_version <= QUIC_VERSION_39) { + if (GetParam().version.transport_version != QUIC_VERSION_41) { EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER, QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); } else { @@ -749,7 +749,7 @@ creator_.UpdatePacketNumberLength( 1, UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize); - if (GetParam().version.transport_version <= QUIC_VERSION_39) { + if (GetParam().version.transport_version != QUIC_VERSION_41) { EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER, QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); } else {
diff --git a/net/quic/core/quic_sent_packet_manager.cc b/net/quic/core/quic_sent_packet_manager.cc index fa7ca1f7..5cb7eb53 100644 --- a/net/quic/core/quic_sent_packet_manager.cc +++ b/net/quic/core/quic_sent_packet_manager.cc
@@ -93,16 +93,12 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { if (config.HasReceivedInitialRoundTripTimeUs() && config.ReceivedInitialRoundTripTimeUs() > 0) { - rtt_stats_.set_initial_rtt_us( - std::max(kMinInitialRoundTripTimeUs, - std::min(kMaxInitialRoundTripTimeUs, - config.ReceivedInitialRoundTripTimeUs()))); + SetInitialRtt(QuicTime::Delta::FromMicroseconds( + config.ReceivedInitialRoundTripTimeUs())); } else if (config.HasInitialRoundTripTimeUsToSend() && config.GetInitialRoundTripTimeUsToSend() > 0) { - rtt_stats_.set_initial_rtt_us( - std::max(kMinInitialRoundTripTimeUs, - std::min(kMaxInitialRoundTripTimeUs, - config.GetInitialRoundTripTimeUsToSend()))); + SetInitialRtt(QuicTime::Delta::FromMicroseconds( + config.GetInitialRoundTripTimeUsToSend())); } if (GetQuicReloadableFlag(quic_max_ack_delay) && config.HasClientSentConnectionOption(kMAD0, perspective_)) { @@ -177,20 +173,20 @@ void QuicSentPacketManager::ResumeConnectionState( const CachedNetworkParameters& cached_network_params, bool max_bandwidth_resumption) { - if (cached_network_params.has_min_rtt_ms()) { - uint32_t initial_rtt_us = - kNumMicrosPerMilli * cached_network_params.min_rtt_ms(); - rtt_stats_.set_initial_rtt_us( - std::max(kMinInitialRoundTripTimeUs, - std::min(kMaxInitialRoundTripTimeUs, initial_rtt_us))); - } - QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond( max_bandwidth_resumption ? cached_network_params.max_bandwidth_estimate_bytes_per_second() : cached_network_params.bandwidth_estimate_bytes_per_second()); QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms()); + AdjustNetworkParameters(bandwidth, rtt); +} + +void QuicSentPacketManager::AdjustNetworkParameters(QuicBandwidth bandwidth, + QuicTime::Delta rtt) { + if (!rtt.IsZero()) { + SetInitialRtt(rtt); + } send_algorithm_->AdjustNetworkParameters(bandwidth, rtt); } @@ -778,11 +774,8 @@ const { // This is equivalent to the TailLossProbeDelay, but slightly more aggressive // because crypto handshake messages don't incur a delayed ack time. - QuicTime::Delta srtt = rtt_stats_.smoothed_rtt(); + QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt(); int64_t delay_ms; - if (srtt.IsZero()) { - srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us()); - } if (conservative_handshake_retransmits_) { delay_ms = std::max(kConservativeMinHandshakeTimeoutMs, static_cast<int64_t>(2 * srtt.ToMilliseconds())); @@ -795,10 +788,7 @@ } const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { - QuicTime::Delta srtt = rtt_stats_.smoothed_rtt(); - if (srtt.IsZero()) { - srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us()); - } + QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt(); if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) { return QuicTime::Delta::FromMilliseconds( std::max(kMinTailLossProbeTimeoutMs, @@ -905,7 +895,7 @@ pacing_sender_.set_sender(send_algorithm); } -void QuicSentPacketManager::OnConnectionMigration(PeerAddressChangeType type) { +void QuicSentPacketManager::OnConnectionMigration(AddressChangeType type) { if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) { // Rtt and cwnd do not need to be reset when the peer address change is // considered to be caused by NATs. @@ -961,4 +951,12 @@ unacked_packets_.SetSessionNotifier(session_notifier); } +void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt) { + const QuicTime::Delta min_rtt = + QuicTime::Delta::FromMicroseconds(kMinInitialRoundTripTimeUs); + const QuicTime::Delta max_rtt = + QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs); + rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt))); +} + } // namespace net
diff --git a/net/quic/core/quic_sent_packet_manager.h b/net/quic/core/quic_sent_packet_manager.h index a608ba1a..658a2dae 100644 --- a/net/quic/core/quic_sent_packet_manager.h +++ b/net/quic/core/quic_sent_packet_manager.h
@@ -122,6 +122,10 @@ // and the previously encrypted data needs to be encrypted with a new key. void RetransmitUnackedPackets(TransmissionType retransmission_type); + // Notify the sent packet manager of an external network measurement or + // prediction for either |bandwidth| or |rtt|; either can be empty. + void AdjustNetworkParameters(QuicBandwidth bandwidth, QuicTime::Delta rtt); + // Retransmits the oldest pending packet there is still a tail loss probe // pending. Invoked after OnRetransmissionTimeout. bool MaybeRetransmitTailLossProbe(); @@ -209,7 +213,7 @@ void CancelRetransmissionsForStream(QuicStreamId stream_id); // Called when peer address changes and the connection migrates. - void OnConnectionMigration(PeerAddressChangeType type); + void OnConnectionMigration(AddressChangeType type); void SetDebugDelegate(DebugDelegate* debug_delegate); @@ -335,6 +339,9 @@ // number of times. void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm); + // Sets the initial RTT of the connection. + void SetInitialRtt(QuicTime::Delta rtt); + // Newly serialized retransmittable packets are added to this map, which // contains owning pointers to any contained frames. If a packet is // retransmitted, this map will contain entries for both the old and the new
diff --git a/net/quic/core/quic_sent_packet_manager_test.cc b/net/quic/core/quic_sent_packet_manager_test.cc index ad554c70..f8b944f 100644 --- a/net/quic/core/quic_sent_packet_manager_test.cc +++ b/net/quic/core/quic_sent_packet_manager_test.cc
@@ -16,13 +16,13 @@ #include "net/quic/test_tools/quic_sent_packet_manager_peer.h" #include "net/quic/test_tools/quic_test_utils.h" +using testing::_; using testing::AnyNumber; using testing::IsEmpty; using testing::Not; using testing::Pointwise; using testing::Return; using testing::StrictMock; -using testing::_; namespace net { namespace test { @@ -1051,15 +1051,14 @@ // Check the min. RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); - rtt_stats->set_initial_rtt_us(1 * kNumMicrosPerMilli); + rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1)); EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10), manager_.GetRetransmissionTime()); // Test with a standard smoothed RTT. - rtt_stats->set_initial_rtt_us(100 * kNumMicrosPerMilli); + rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100)); - QuicTime::Delta srtt = - QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); + QuicTime::Delta srtt = rtt_stats->initial_rtt(); QuicTime expected_time = clock_.Now() + 1.5 * srtt; EXPECT_EQ(expected_time, manager_.GetRetransmissionTime()); @@ -1092,15 +1091,14 @@ // Check the min. RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); - rtt_stats->set_initial_rtt_us(1 * kNumMicrosPerMilli); + rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1)); EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(25), manager_.GetRetransmissionTime()); // Test with a standard smoothed RTT. - rtt_stats->set_initial_rtt_us(100 * kNumMicrosPerMilli); + rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100)); - QuicTime::Delta srtt = - QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); + QuicTime::Delta srtt = rtt_stats->initial_rtt(); QuicTime expected_time = clock_.Now() + 2 * srtt; EXPECT_EQ(expected_time, manager_.GetRetransmissionTime()); @@ -1121,14 +1119,13 @@ // Check the min. RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); - rtt_stats->set_initial_rtt_us(1 * kNumMicrosPerMilli); + rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1)); EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10), manager_.GetRetransmissionTime()); // Test with a standard smoothed RTT. - rtt_stats->set_initial_rtt_us(100 * kNumMicrosPerMilli); - QuicTime::Delta srtt = - QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()); + rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100)); + QuicTime::Delta srtt = rtt_stats->initial_rtt(); QuicTime::Delta expected_tlp_delay = 2 * srtt; QuicTime expected_time = clock_.Now() + expected_tlp_delay; EXPECT_EQ(expected_time, manager_.GetRetransmissionTime()); @@ -1552,40 +1549,37 @@ } TEST_F(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) { - uint32_t initial_rtt_us = 325000; - EXPECT_NE(initial_rtt_us, - manager_.GetRttStats()->smoothed_rtt().ToMicroseconds()); + QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(325); + EXPECT_NE(initial_rtt, manager_.GetRttStats()->smoothed_rtt()); QuicConfig config; - config.SetInitialRoundTripTimeUsToSend(initial_rtt_us); + config.SetInitialRoundTripTimeUsToSend(initial_rtt.ToMicroseconds()); EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); manager_.SetFromConfig(config); - EXPECT_EQ(0, manager_.GetRttStats()->smoothed_rtt().ToMicroseconds()); - EXPECT_EQ(initial_rtt_us, manager_.GetRttStats()->initial_rtt_us()); + EXPECT_EQ(QuicTime::Delta::Zero(), manager_.GetRttStats()->smoothed_rtt()); + EXPECT_EQ(initial_rtt, manager_.GetRttStats()->initial_rtt()); } TEST_F(QuicSentPacketManagerTest, ResumeConnectionState) { // The sent packet manager should use the RTT from CachedNetworkParameters if // it is provided. - const int kRttMs = 1234; + const QuicTime::Delta kRtt = QuicTime::Delta::FromMilliseconds(1234); CachedNetworkParameters cached_network_params; - cached_network_params.set_min_rtt_ms(kRttMs); + cached_network_params.set_min_rtt_ms(kRtt.ToMilliseconds()); - EXPECT_CALL(*send_algorithm_, AdjustNetworkParameters( - QuicBandwidth::Zero(), - QuicTime::Delta::FromMilliseconds(kRttMs))); + EXPECT_CALL(*send_algorithm_, + AdjustNetworkParameters(QuicBandwidth::Zero(), kRtt)); manager_.ResumeConnectionState(cached_network_params, false); - EXPECT_EQ(kRttMs * kNumMicrosPerMilli, - static_cast<uint64_t>(manager_.GetRttStats()->initial_rtt_us())); + EXPECT_EQ(kRtt, manager_.GetRttStats()->initial_rtt()); } TEST_F(QuicSentPacketManagerTest, ConnectionMigrationUnspecifiedChange) { RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); - int64_t default_init_rtt = rtt_stats->initial_rtt_us(); - rtt_stats->set_initial_rtt_us(default_init_rtt * 2); - EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt_us()); + QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt(); + rtt_stats->set_initial_rtt(default_init_rtt * 2); + EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt()); QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1); EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount()); @@ -1595,16 +1589,16 @@ EXPECT_CALL(*send_algorithm_, OnConnectionMigration()); manager_.OnConnectionMigration(IPV4_TO_IPV4_CHANGE); - EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt_us()); + EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt()); EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount()); EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount()); } TEST_F(QuicSentPacketManagerTest, ConnectionMigrationIPSubnetChange) { RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); - int64_t default_init_rtt = rtt_stats->initial_rtt_us(); - rtt_stats->set_initial_rtt_us(default_init_rtt * 2); - EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt_us()); + QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt(); + rtt_stats->set_initial_rtt(default_init_rtt * 2); + EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt()); QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1); EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount()); @@ -1613,16 +1607,16 @@ manager_.OnConnectionMigration(IPV4_SUBNET_CHANGE); - EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt_us()); + EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt()); EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount()); EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount()); } TEST_F(QuicSentPacketManagerTest, ConnectionMigrationPortChange) { RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); - int64_t default_init_rtt = rtt_stats->initial_rtt_us(); - rtt_stats->set_initial_rtt_us(default_init_rtt * 2); - EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt_us()); + QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt(); + rtt_stats->set_initial_rtt(default_init_rtt * 2); + EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt()); QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1); EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount()); @@ -1631,7 +1625,7 @@ manager_.OnConnectionMigration(PORT_CHANGE); - EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt_us()); + EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt()); EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount()); EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount()); }
diff --git a/net/quic/core/quic_server_session_base_test.cc b/net/quic/core/quic_server_session_base_test.cc index 3bbca7b..c201f52 100644 --- a/net/quic/core/quic_server_session_base_test.cc +++ b/net/quic/core/quic_server_session_base_test.cc
@@ -37,8 +37,8 @@ #include "net/tools/quic/test_tools/mock_quic_session_visitor.h" using std::string; -using testing::StrictMock; using testing::_; +using testing::StrictMock; namespace net { namespace test { @@ -435,9 +435,8 @@ // Seed an rtt measurement equal to the initial default rtt. RttStats* rtt_stats = const_cast<RttStats*>(sent_packet_manager->GetRttStats()); - rtt_stats->UpdateRtt( - QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()), - QuicTime::Delta::Zero(), QuicTime::Zero()); + rtt_stats->UpdateRtt(rtt_stats->initial_rtt(), QuicTime::Delta::Zero(), + QuicTime::Zero()); QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate( &bandwidth_recorder, bandwidth_estimate_kbytes_per_second); QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
diff --git a/net/quic/core/quic_session.h b/net/quic/core/quic_session.h index 7ed2e91..c0c8f25 100644 --- a/net/quic/core/quic_session.h +++ b/net/quic/core/quic_session.h
@@ -105,7 +105,7 @@ const QuicSocketAddress& peer_address) override; void OnCanWrite() override; void OnCongestionWindowChange(QuicTime /*now*/) override {} - void OnConnectionMigration(PeerAddressChangeType type) override {} + void OnConnectionMigration(AddressChangeType type) override {} // Deletes streams that are safe to be deleted now that it's safe to do so (no // other operations are being done on the streams at this time). void PostProcessAfterData() override;
diff --git a/net/quic/core/quic_types.h b/net/quic/core/quic_types.h index fef02ca..ac7b81ae 100644 --- a/net/quic/core/quic_types.h +++ b/net/quic/core/quic_types.h
@@ -231,7 +231,7 @@ NUM_ENCRYPTION_LEVELS, }; -enum PeerAddressChangeType { +enum AddressChangeType { // IP address and port remain unchanged. NO_CHANGE, // Port changed, but IP address remains unchanged.
diff --git a/net/quic/core/quic_unacked_packet_map_test.cc b/net/quic/core/quic_unacked_packet_map_test.cc index c1c9c9f9..beb50e2 100644 --- a/net/quic/core/quic_unacked_packet_map_test.cc +++ b/net/quic/core/quic_unacked_packet_map_test.cc
@@ -8,8 +8,6 @@ #include "net/quic/platform/api/quic_test.h" #include "net/quic/test_tools/quic_test_utils.h" -using testing::_; - namespace net { namespace test { namespace {
diff --git a/net/quic/core/quic_utils.cc b/net/quic/core/quic_utils.cc index 39ccb665..6bb4ed5 100644 --- a/net/quic/core/quic_utils.cc +++ b/net/quic/core/quic_utils.cc
@@ -163,7 +163,7 @@ return "INVALID_TRANSMISSION_TYPE"; } -string QuicUtils::PeerAddressChangeTypeToString(PeerAddressChangeType type) { +string QuicUtils::AddressChangeTypeToString(AddressChangeType type) { switch (type) { RETURN_STRING_LITERAL(NO_CHANGE); RETURN_STRING_LITERAL(PORT_CHANGE); @@ -173,11 +173,11 @@ RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE); RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE); } - return "INVALID_PEER_ADDRESS_CHANGE_TYPE"; + return "INVALID_ADDRESS_CHANGE_TYPE"; } // static -PeerAddressChangeType QuicUtils::DetermineAddressChangeType( +AddressChangeType QuicUtils::DetermineAddressChangeType( const QuicSocketAddress& old_address, const QuicSocketAddress& new_address) { if (!old_address.IsInitialized() || !new_address.IsInitialized() ||
diff --git a/net/quic/core/quic_utils.h b/net/quic/core/quic_utils.h index de612dc..b3dbaae97 100644 --- a/net/quic/core/quic_utils.h +++ b/net/quic/core/quic_utils.h
@@ -51,12 +51,12 @@ // Returns TransmissionType as a char* static const char* TransmissionTypeToString(TransmissionType type); - // Returns PeerAddressChangeType as a std::string. - static std::string PeerAddressChangeTypeToString(PeerAddressChangeType type); + // Returns AddressChangeType as a std::string. + static std::string AddressChangeTypeToString(AddressChangeType type); // Determines and returns change type of address change from |old_address| to // |new_address|. - static PeerAddressChangeType DetermineAddressChangeType( + static AddressChangeType DetermineAddressChangeType( const QuicSocketAddress& old_address, const QuicSocketAddress& new_address);
diff --git a/net/quic/core/quic_version_manager.cc b/net/quic/core/quic_version_manager.cc index 489b7be..031e6e2 100644 --- a/net/quic/core/quic_version_manager.cc +++ b/net/quic/core/quic_version_manager.cc
@@ -11,8 +11,11 @@ QuicVersionManager::QuicVersionManager( ParsedQuicVersionVector supported_versions) - : enable_version_43_(GetQuicFlag(FLAGS_quic_enable_version_43)), - enable_version_42_(GetQuicFlag(FLAGS_quic_enable_version_42)), + : enable_version_99_(GetQuicFlag(FLAGS_quic_enable_version_99)), + enable_version_43_(GetQuicFlag(FLAGS_quic_enable_version_43)), + enable_version_42_( + GetQuicReloadableFlag(quic_enable_version_42) && + GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)), allowed_supported_versions_(std::move(supported_versions)) { RefilterSupportedVersions(); } @@ -31,10 +34,16 @@ } void QuicVersionManager::MaybeRefilterSupportedVersions() { - if (enable_version_43_ != GetQuicFlag(FLAGS_quic_enable_version_43) || - enable_version_42_ != GetQuicFlag(FLAGS_quic_enable_version_42)) { + if (enable_version_99_ != GetQuicFlag(FLAGS_quic_enable_version_99) || + enable_version_43_ != GetQuicFlag(FLAGS_quic_enable_version_43) || + enable_version_42_ != + (GetQuicReloadableFlag(quic_enable_version_42) && + GetQuicReloadableFlag(quic_allow_receiving_overlapping_data))) { + enable_version_99_ = GetQuicFlag(FLAGS_quic_enable_version_99); enable_version_43_ = GetQuicFlag(FLAGS_quic_enable_version_43); - enable_version_42_ = GetQuicFlag(FLAGS_quic_enable_version_42); + enable_version_42_ = + (GetQuicReloadableFlag(quic_enable_version_42) && + GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)); RefilterSupportedVersions(); } }
diff --git a/net/quic/core/quic_version_manager.h b/net/quic/core/quic_version_manager.h index 0982873..147717c 100644 --- a/net/quic/core/quic_version_manager.h +++ b/net/quic/core/quic_version_manager.h
@@ -35,9 +35,12 @@ } private: + // FLAGS_quic_enable_version_99 + bool enable_version_99_; // FLAGS_quic_enable_version_43 bool enable_version_43_; - // FLAGS_quic_enable_version_42 + // FLAGS_quic_reloadable_flag_quic_enable_version_42 and + // FLAGS_quic_reloadable_flag_quic_allow_receiving_overlapping_data. bool enable_version_42_; // The list of versions that may be supported. ParsedQuicVersionVector allowed_supported_versions_;
diff --git a/net/quic/core/quic_version_manager_test.cc b/net/quic/core/quic_version_manager_test.cc index ab8c101..5d36e7ea 100644 --- a/net/quic/core/quic_version_manager_test.cc +++ b/net/quic/core/quic_version_manager_test.cc
@@ -5,6 +5,7 @@ #include "net/quic/core/quic_version_manager.h" #include "net/quic/core/quic_versions.h" +#include "net/quic/platform/api/quic_arraysize.h" #include "net/quic/platform/api/quic_flags.h" #include "net/quic/platform/api/quic_test.h" #include "net/quic/test_tools/quic_test_utils.h" @@ -16,8 +17,11 @@ class QuicVersionManagerTest : public QuicTest {}; TEST_F(QuicVersionManagerTest, QuicVersionManager) { + static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 8u, + "Supported versions out of sync"); + SetQuicFlag(&FLAGS_quic_enable_version_99, false); SetQuicFlag(&FLAGS_quic_enable_version_43, false); - SetQuicFlag(&FLAGS_quic_enable_version_42, false); + SetQuicReloadableFlag(quic_enable_version_42, false); QuicVersionManager manager(AllSupportedVersions()); EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()), @@ -29,7 +33,8 @@ EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedTransportVersions()[3]); EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedTransportVersions()[4]); - SetQuicFlag(&FLAGS_quic_enable_version_42, true); + SetQuicReloadableFlag(quic_enable_version_42, true); + SetQuicReloadableFlag(quic_allow_receiving_overlapping_data, true); ASSERT_EQ(6u, manager.GetSupportedTransportVersions().size()); EXPECT_EQ(QUIC_VERSION_42, manager.GetSupportedTransportVersions()[0]); EXPECT_EQ(QUIC_VERSION_41, manager.GetSupportedTransportVersions()[1]); @@ -38,7 +43,6 @@ EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedTransportVersions()[4]); EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedTransportVersions()[5]); - // enable version 43; ensure that all versions are now supported.. SetQuicFlag(&FLAGS_quic_enable_version_43, true); ASSERT_EQ(7u, manager.GetSupportedTransportVersions().size()); EXPECT_EQ(QUIC_VERSION_43, manager.GetSupportedTransportVersions()[0]); @@ -49,16 +53,20 @@ EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedTransportVersions()[5]); EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedTransportVersions()[6]); + SetQuicFlag(&FLAGS_quic_enable_version_99, true); + ASSERT_EQ(8u, manager.GetSupportedTransportVersions().size()); + EXPECT_EQ(QUIC_VERSION_99, manager.GetSupportedTransportVersions()[0]); + EXPECT_EQ(QUIC_VERSION_43, manager.GetSupportedTransportVersions()[1]); + EXPECT_EQ(QUIC_VERSION_42, manager.GetSupportedTransportVersions()[2]); + EXPECT_EQ(QUIC_VERSION_41, manager.GetSupportedTransportVersions()[3]); + EXPECT_EQ(QUIC_VERSION_39, manager.GetSupportedTransportVersions()[4]); + EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedTransportVersions()[5]); + EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedTransportVersions()[6]); + EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedTransportVersions()[7]); + + // Ensure that all versions are now supported. EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()), manager.GetSupportedTransportVersions()); - ASSERT_EQ(7u, manager.GetSupportedTransportVersions().size()); - EXPECT_EQ(QUIC_VERSION_43, manager.GetSupportedTransportVersions()[0]); - EXPECT_EQ(QUIC_VERSION_42, manager.GetSupportedTransportVersions()[1]); - EXPECT_EQ(QUIC_VERSION_41, manager.GetSupportedTransportVersions()[2]); - EXPECT_EQ(QUIC_VERSION_39, manager.GetSupportedTransportVersions()[3]); - EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedTransportVersions()[4]); - EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedTransportVersions()[5]); - EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedTransportVersions()[6]); } } // namespace
diff --git a/net/quic/core/quic_versions.cc b/net/quic/core/quic_versions.cc index d9fec40..bd0f353 100644 --- a/net/quic/core/quic_versions.cc +++ b/net/quic/core/quic_versions.cc
@@ -63,6 +63,8 @@ return MakeVersionLabel(proto, '0', '4', '2'); case QUIC_VERSION_43: return MakeVersionLabel(proto, '0', '4', '3'); + case QUIC_VERSION_99: + return MakeVersionLabel(proto, '0', '9', '9'); default: // This shold be an ERROR because we should never attempt to convert an // invalid QuicTransportVersion to be written to the wire. @@ -142,13 +144,22 @@ ParsedQuicVersionVector filtered_versions; filtered_versions.reserve(versions.size()); for (ParsedQuicVersion version : versions) { - if (version.transport_version == QUIC_VERSION_43) { + if (version.transport_version == QUIC_VERSION_99) { + if (GetQuicFlag(FLAGS_quic_enable_version_99) && + GetQuicFlag(FLAGS_quic_enable_version_43) && + GetQuicReloadableFlag(quic_enable_version_42) && + GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)) { + filtered_versions.push_back(version); + } + } else if (version.transport_version == QUIC_VERSION_43) { if (GetQuicFlag(FLAGS_quic_enable_version_43) && - GetQuicFlag(FLAGS_quic_enable_version_42)) { + GetQuicReloadableFlag(quic_enable_version_42) && + GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)) { filtered_versions.push_back(version); } } else if (version.transport_version == QUIC_VERSION_42) { - if (GetQuicFlag(FLAGS_quic_enable_version_42)) { + if (GetQuicReloadableFlag(quic_enable_version_42) && + GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)) { filtered_versions.push_back(version); } } else { @@ -228,6 +239,7 @@ RETURN_STRING_LITERAL(QUIC_VERSION_41); RETURN_STRING_LITERAL(QUIC_VERSION_42); RETURN_STRING_LITERAL(QUIC_VERSION_43); + RETURN_STRING_LITERAL(QUIC_VERSION_99); default: return "QUIC_VERSION_UNSUPPORTED"; }
diff --git a/net/quic/core/quic_versions.h b/net/quic/core/quic_versions.h index b99596ff..f843e1c 100644 --- a/net/quic/core/quic_versions.h +++ b/net/quic/core/quic_versions.h
@@ -33,9 +33,10 @@ // WINDOW_UPDATE every 20 sent packets which do not // contain retransmittable frames. QUIC_VERSION_41 = 41, // RST_STREAM, ACK and STREAM frames match IETF format. - QUIC_VERSION_42 = 42, // Initial packet number is randomly chosen from - // [1:2^31], + QUIC_VERSION_42 = 42, // Allows receiving overlapping stream data. QUIC_VERSION_43 = 43, // Use IETF packet header format. + QUIC_VERSION_99 = 99, // Dumping ground for IETF QUIC changes which are not + // yet ready for production. // IMPORTANT: if you are adding to this list, follow the instructions at // http://sites/quic/adding-and-removing-versions @@ -100,8 +101,8 @@ // IMPORTANT: if you are adding to this list, follow the instructions at // http://sites/quic/adding-and-removing-versions static const QuicTransportVersion kSupportedTransportVersions[] = { - QUIC_VERSION_43, QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, - QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}; + QUIC_VERSION_99, QUIC_VERSION_43, QUIC_VERSION_42, QUIC_VERSION_41, + QUIC_VERSION_39, QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}; // This vector contains all crypto handshake protocols that are supported. static const HandshakeProtocol kSupportedHandshakeProtocols[] = {
diff --git a/net/quic/core/quic_versions_test.cc b/net/quic/core/quic_versions_test.cc index 1a4a553a5..57cc42c 100644 --- a/net/quic/core/quic_versions_test.cc +++ b/net/quic/core/quic_versions_test.cc
@@ -365,7 +365,7 @@ // yet a typo was made in doing the #defines and it was caught // only in some test far removed from here... Better safe than sorry. TEST_F(QuicVersionsTest, CheckVersionNumbersForTypos) { - static_assert(QUIC_ARRAYSIZE(net::kSupportedTransportVersions) == 7u, + static_assert(QUIC_ARRAYSIZE(net::kSupportedTransportVersions) == 8u, "Supported versions out of sync"); EXPECT_EQ(QUIC_VERSION_35, 35); EXPECT_EQ(QUIC_VERSION_37, 37); @@ -374,6 +374,7 @@ EXPECT_EQ(QUIC_VERSION_41, 41); EXPECT_EQ(QUIC_VERSION_42, 42); EXPECT_EQ(QUIC_VERSION_43, 43); + EXPECT_EQ(QUIC_VERSION_99, 99); } } // namespace } // namespace test
diff --git a/net/quic/http/quic_http_structures_test.cc b/net/quic/http/quic_http_structures_test.cc index a1d00dfa..c17d684 100644 --- a/net/quic/http/quic_http_structures_test.cc +++ b/net/quic/http/quic_http_structures_test.cc
@@ -24,7 +24,6 @@ #include "testing/gtest/include/gtest/gtest.h" using ::testing::AssertionResult; -using ::testing::AssertionSuccess; using ::testing::Combine; using ::testing::Contains; using ::testing::HasSubstr;
diff --git a/net/quic/platform/api/quic_containers.h b/net/quic/platform/api/quic_containers.h index 3aeb37d2..c83c63a 100644 --- a/net/quic/platform/api/quic_containers.h +++ b/net/quic/platform/api/quic_containers.h
@@ -32,6 +32,8 @@ // Used for maps that are typically small, then it is faster than (for example) // hash_map which is optimized for large data sets. QuicSmallMap upgrades itself // automatically to a QuicSmallMapImpl-specified map when it runs out of space. +// +// DOES NOT GUARANTEE POINTER OR ITERATOR STABILITY! template <typename Key, typename Value, int Size> using QuicSmallMap = QuicSmallMapImpl<Key, Value, Size>;
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index adabaca1..40efdd0 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h
@@ -310,7 +310,7 @@ MOCK_METHOD0(OnWriteBlocked, void()); MOCK_METHOD0(OnCanWrite, void()); MOCK_METHOD1(OnCongestionWindowChange, void(QuicTime now)); - MOCK_METHOD1(OnConnectionMigration, void(PeerAddressChangeType type)); + MOCK_METHOD1(OnConnectionMigration, void(AddressChangeType type)); MOCK_METHOD0(OnPathDegrading, void()); MOCK_CONST_METHOD0(WillingAndAbleToWrite, bool()); MOCK_CONST_METHOD0(HasPendingHandshake, bool());
diff --git a/net/quic/test_tools/simulator/quic_endpoint.h b/net/quic/test_tools/simulator/quic_endpoint.h index 818cdfb2..4f2a64d4 100644 --- a/net/quic/test_tools/simulator/quic_endpoint.h +++ b/net/quic/test_tools/simulator/quic_endpoint.h
@@ -90,7 +90,7 @@ const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address) override {} void OnCongestionWindowChange(QuicTime now) override {} - void OnConnectionMigration(PeerAddressChangeType type) override {} + void OnConnectionMigration(AddressChangeType type) override {} void OnPathDegrading() override {} void PostProcessAfterData() override {} void OnAckNeedsRetransmittableFrame() override {}
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index d6863c5..857d45f 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc
@@ -1353,8 +1353,8 @@ TEST_P(EndToEndTest, ClientSuggestsRTT) { // Client suggests initial RTT, verify it is used. - const uint32_t kInitialRTT = 20000; - client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT); + const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000); + client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds()); ASSERT_TRUE(Initialize()); EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed()); @@ -1371,9 +1371,9 @@ GetSentPacketManagerFromFirstServerSession(); EXPECT_EQ(kInitialRTT, - client_sent_packet_manager.GetRttStats()->initial_rtt_us()); + client_sent_packet_manager.GetRttStats()->initial_rtt()); EXPECT_EQ(kInitialRTT, - server_sent_packet_manager->GetRttStats()->initial_rtt_us()); + server_sent_packet_manager->GetRttStats()->initial_rtt()); server_thread_->Resume(); } @@ -1403,7 +1403,7 @@ const RttStats& server_rtt_stats = *session->connection()->sent_packet_manager().GetRttStats(); EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs), - server_rtt_stats.initial_rtt_us()); + server_rtt_stats.initial_rtt().ToMicroseconds()); EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs), server_rtt_stats.smoothed_rtt().ToMicroseconds()); server_thread_->Resume(); @@ -1433,8 +1433,8 @@ EXPECT_FALSE( client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite()); // Expect the default rtt of 100ms. - EXPECT_EQ(static_cast<int64_t>(100 * kNumMicrosPerMilli), - server_sent_packet_manager.GetRttStats()->initial_rtt_us()); + EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), + server_sent_packet_manager.GetRttStats()->initial_rtt()); // Ensure the bandwidth is valid. client_sent_packet_manager.BandwidthEstimate(); server_sent_packet_manager.BandwidthEstimate();
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc index cb565a13..7fc7dd0 100644 --- a/net/tools/quic/quic_dispatcher_test.cc +++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -555,10 +555,12 @@ } TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) { - static_assert(arraysize(kSupportedTransportVersions) == 7u, + static_assert(arraysize(kSupportedTransportVersions) == 8u, "Supported versions out of sync"); - SetQuicFlag(&FLAGS_quic_enable_version_42, true); + SetQuicReloadableFlag(quic_enable_version_42, true); + SetQuicReloadableFlag(quic_allow_receiving_overlapping_data, true); SetQuicFlag(&FLAGS_quic_enable_version_43, true); + SetQuicFlag(&FLAGS_quic_enable_version_99, true); QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5); QuicConnectionId connection_id = 1; @@ -639,7 +641,7 @@ PACKET_6BYTE_PACKET_NUMBER, 1); // Turn off version 42. - SetQuicFlag(&FLAGS_quic_enable_version_42, false); + SetQuicReloadableFlag(quic_enable_version_42, false); ++connection_id; EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address, QuicStringPiece("hq"))) @@ -650,7 +652,7 @@ PACKET_6BYTE_PACKET_NUMBER, 1); // Turn on version 42. - SetQuicFlag(&FLAGS_quic_enable_version_42, true); + SetQuicReloadableFlag(quic_enable_version_42, true); ++connection_id; EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address, QuicStringPiece("hq")))
diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc index 0ceca2d3..6c82417 100644 --- a/net/tools/quic/test_tools/quic_test_client.cc +++ b/net/tools/quic/test_tools/quic_test_client.cc
@@ -29,7 +29,6 @@ #include "net/tools/quic/test_tools/quic_client_peer.h" using std::string; -using testing::_; namespace net { namespace test { @@ -331,7 +330,6 @@ } while (client()->WaitForEvents()) { } - return; } ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
diff --git a/pdf/DEPS b/pdf/DEPS index d088805..6e454722 100644 --- a/pdf/DEPS +++ b/pdf/DEPS
@@ -4,6 +4,7 @@ "+ppapi", "+ui/base/window_open_disposition.h", "+ui/events/keycodes/keyboard_codes.h", + "+ui/gfx/geometry/point_f.h", "+ui/gfx/range/range.h", "+v8/include/v8.h" ]
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index 1bb3729..d19690d4 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -41,6 +41,7 @@ #include "ppapi/cpp/var_array.h" #include "ppapi/cpp/var_dictionary.h" #include "ui/events/keycodes/keyboard_codes.h" +#include "ui/gfx/geometry/point_f.h" namespace chrome_pdf { @@ -682,15 +683,15 @@ dict.Get(pp::Var(kJSPageX)).is_int() && dict.Get(pp::Var(kJSPageY)).is_int() && dict.Get(pp::Var(kJSId)).is_int()) { - std::pair<int, int> xy = - engine_->TransformPagePoint(dict.Get(pp::Var(kJSPageNumber)).AsInt(), - {dict.Get(pp::Var(kJSPageX)).AsInt(), - dict.Get(pp::Var(kJSPageY)).AsInt()}); + gfx::PointF page_xy(dict.Get(pp::Var(kJSPageX)).AsInt(), + dict.Get(pp::Var(kJSPageY)).AsInt()); + gfx::PointF device_xy = engine_->TransformPagePoint( + dict.Get(pp::Var(kJSPageNumber)).AsInt(), page_xy); pp::VarDictionary reply; reply.Set(pp::Var(kType), pp::Var(kJSTransformPagePointReplyType)); - reply.Set(pp::Var(kJSPositionX), xy.first); - reply.Set(pp::Var(kJSPositionY), xy.second); + reply.Set(pp::Var(kJSPositionX), device_xy.x()); + reply.Set(pp::Var(kJSPositionY), device_xy.y()); reply.Set(pp::Var(kJSId), dict.Get(pp::Var(kJSId)).AsInt()); PostMessage(reply); } else {
diff --git a/pdf/pdf_engine.h b/pdf/pdf_engine.h index cbb6280..9cd6a5f 100644 --- a/pdf/pdf_engine.h +++ b/pdf/pdf_engine.h
@@ -30,6 +30,7 @@ #include "ppapi/cpp/url_loader.h" #include "ppapi/cpp/var_array.h" #include "ui/base/window_open_disposition.h" +#include "ui/gfx/geometry/point_f.h" #if defined(OS_WIN) typedef void (*PDFEnsureTypefaceCharactersAccessible)(const LOGFONT* font, @@ -302,9 +303,8 @@ // Gets the 0-based page number of |destination|, or -1 if it does not exist. virtual int GetNamedDestinationPage(const std::string& destination) = 0; // Transforms an (x, y) point in page coordinates to screen coordinates. - virtual std::pair<int, int> TransformPagePoint( - int page_index, - std::pair<int, int> page_xy) = 0; + virtual gfx::PointF TransformPagePoint(int page_index, + const gfx::PointF& page_xy) = 0; // Gets the index of the most visible page, or -1 if none are visible. virtual int GetMostVisiblePage() = 0; // Gets the rectangle of the page including shadow.
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 7b4d7b2..3d4e0e1 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -2651,15 +2651,14 @@ FPDF_DEST dest = FPDFBookmark_GetDest(doc_, bookmark); // Some bookmarks don't have a page to select. if (dest) { - unsigned long page_index = FPDFDest_GetPageIndex(doc_, dest); - if (page_index < pages_.size() && - base::IsValueInRangeForNumericType<int32_t>(page_index)) { - dict.Set(pp::Var("page"), pp::Var(static_cast<int32_t>(page_index))); + int page_index = FPDFDest_GetDestPageIndex(doc_, dest); + if (PageIndexInBounds(page_index)) { + dict.Set(pp::Var("page"), pp::Var(page_index)); - base::Optional<std::pair<float, float>> xy = + base::Optional<gfx::PointF> xy = pages_[page_index]->GetPageXYTarget(dest); if (xy) - dict.Set(pp::Var("y"), pp::Var(static_cast<int>(xy.value().second))); + dict.Set(pp::Var("y"), pp::Var(static_cast<int>(xy.value().y()))); } } else { // Extract URI for bookmarks linking to an external page. @@ -2710,12 +2709,12 @@ if (bookmark) dest = FPDFBookmark_GetDest(doc_, bookmark); } - return dest ? FPDFDest_GetPageIndex(doc_, dest) : -1; + return dest ? FPDFDest_GetDestPageIndex(doc_, dest) : -1; } -std::pair<int, int> PDFiumEngine::TransformPagePoint( - int page_index, - std::pair<int, int> page_xy) { +gfx::PointF PDFiumEngine::TransformPagePoint(int page_index, + const gfx::PointF& page_xy) { + DCHECK(PageIndexInBounds(page_index)); return pages_[page_index]->TransformPageToScreenXY(page_xy); }
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index da9875e..64643ac 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -80,8 +80,8 @@ int GetNumberOfPages() override; pp::VarArray GetBookmarks() override; int GetNamedDestinationPage(const std::string& destination) override; - std::pair<int, int> TransformPagePoint(int page_index, - std::pair<int, int> page_xy) override; + gfx::PointF TransformPagePoint(int page_index, + const gfx::PointF& page_xy) override; int GetMostVisiblePage() override; pp::Rect GetPageRect(int index) override; pp::Rect GetPageBoundsRect(int index) override;
diff --git a/pdf/pdfium/pdfium_page.cc b/pdf/pdfium/pdfium_page.cc index 6bcc5b2..6f8ede61 100644 --- a/pdf/pdfium/pdfium_page.cc +++ b/pdf/pdfium/pdfium_page.cc
@@ -366,16 +366,14 @@ target->page = page_index; - base::Optional<std::pair<float, float>> xy = GetPageXYTarget(destination); - if (!xy) - return DOCLINK_AREA; + base::Optional<gfx::PointF> xy = GetPageXYTarget(destination); + if (xy) + target->y_in_pixels = TransformPageToScreenXY(xy.value()).y(); - target->y_in_pixels = TransformPageToScreenXY(xy.value()).second; return DOCLINK_AREA; } -base::Optional<std::pair<float, float>> PDFiumPage::GetPageXYTarget( - FPDF_DEST destination) { +base::Optional<gfx::PointF> PDFiumPage::GetPageXYTarget(FPDF_DEST destination) { if (!available_) return {}; @@ -391,18 +389,16 @@ if (!success || !has_x_coord || !has_y_coord) return {}; - return {{x, y}}; + return {gfx::PointF(x, y)}; } -std::pair<float, float> PDFiumPage::TransformPageToScreenXY( - std::pair<float, float> xy) { - if (!available_) { - return {0, 0}; - } +gfx::PointF PDFiumPage::TransformPageToScreenXY(const gfx::PointF& xy) { + if (!available_) + return gfx::PointF(); - pp::FloatRect page_rect(xy.first, xy.second, 0, 0); + pp::FloatRect page_rect(xy.x(), xy.y(), 0, 0); pp::FloatRect pixel_rect(FloatPageRectToPixelRect(GetPage(), page_rect)); - return {pixel_rect.x(), pixel_rect.y()}; + return gfx::PointF(pixel_rect.x(), pixel_rect.y()); } PDFiumPage::Area PDFiumPage::GetURITarget(FPDF_ACTION uri_action,
diff --git a/pdf/pdfium/pdfium_page.h b/pdf/pdfium/pdfium_page.h index f733321..009d4bb 100644 --- a/pdf/pdfium/pdfium_page.h +++ b/pdf/pdfium/pdfium_page.h
@@ -15,6 +15,7 @@ #include "third_party/pdfium/public/fpdf_doc.h" #include "third_party/pdfium/public/fpdf_formfill.h" #include "third_party/pdfium/public/fpdf_text.h" +#include "ui/gfx/geometry/point_f.h" namespace chrome_pdf { @@ -77,11 +78,10 @@ }; // Returns the (x, y) position of a destination in page coordinates. - base::Optional<std::pair<float, float>> GetPageXYTarget( - FPDF_DEST destination); + base::Optional<gfx::PointF> GetPageXYTarget(FPDF_DEST destination); // Transforms an (x, y) position in page coordinates to screen coordinates. - std::pair<float, float> TransformPageToScreenXY(std::pair<float, float> xy); + gfx::PointF TransformPageToScreenXY(const gfx::PointF& xy); // Given a point in the document that's in this page, returns its character // index if it's near a character, and also the type of text.
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index ea834bd..4e43ec1 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -32,8 +32,6 @@ "network_sandbox_hook_linux.h", "network_service.cc", "network_service.h", - "network_service_url_loader_factory.cc", - "network_service_url_loader_factory.h", "proxy_config_service_mojo.cc", "proxy_config_service_mojo.h", "proxy_resolving_client_socket.cc", @@ -64,6 +62,8 @@ "upload_progress_tracker.h", "url_loader.cc", "url_loader.h", + "url_loader_factory.cc", + "url_loader_factory.h", "url_request_context_builder_mojo.cc", "url_request_context_builder_mojo.h", "url_request_context_owner.cc",
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 625df2e9..435af19 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -42,7 +42,6 @@ #include "services/network/http_server_properties_pref_delegate.h" #include "services/network/ignore_errors_cert_verifier.h" #include "services/network/network_service.h" -#include "services/network/network_service_url_loader_factory.h" #include "services/network/proxy_config_service_mojo.h" #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/network_switches.h" @@ -52,6 +51,7 @@ #include "services/network/throttling/throttling_network_transaction_factory.h" #include "services/network/udp_socket_factory.h" #include "services/network/url_loader.h" +#include "services/network/url_loader_factory.h" #include "services/network/url_request_context_builder_mojo.h" namespace network { @@ -157,8 +157,7 @@ mojom::URLLoaderFactoryRequest request, uint32_t process_id) { loader_factory_bindings_.AddBinding( - std::make_unique<NetworkServiceURLLoaderFactory>(this, process_id), - std::move(request)); + std::make_unique<URLLoaderFactory>(this, process_id), std::move(request)); } void NetworkContext::HandleViewCacheRequest(const GURL& url,
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index f869d27..d3aceee7 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -740,21 +740,18 @@ network_context->CreateUDPSocket(mojo::MakeRequest(&server_socket), std::move(receiver_interface_ptr)); network::test::UDPSocketTestHelper helper(&server_socket); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); // Create a client socket to send datagrams. mojom::UDPSocketPtr client_socket; mojom::UDPSocketRequest client_socket_request( mojo::MakeRequest(&client_socket)); - mojom::UDPSocketReceiverPtr client_receiver_ptr; - network_context->CreateUDPSocket(std::move(client_socket_request), - std::move(client_receiver_ptr)); + network_context->CreateUDPSocket(std::move(client_socket_request), nullptr); net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); network::test::UDPSocketTestHelper client_helper(&client_socket); - ASSERT_EQ(net::OK, client_helper.OpenSync(client_addr.GetFamily())); - ASSERT_EQ(net::OK, client_helper.ConnectSync(server_addr, &client_addr)); + ASSERT_EQ(net::OK, + client_helper.ConnectSync(server_addr, nullptr, &client_addr)); // This test assumes that the loopback interface doesn't drop UDP packets for // a small number of packets.
diff --git a/services/network/public/interfaces/udp_socket.mojom b/services/network/public/interfaces/udp_socket.mojom index 16194baf..5ea79d8 100644 --- a/services/network/public/interfaces/udp_socket.mojom +++ b/services/network/public/interfaces/udp_socket.mojom
@@ -35,6 +35,20 @@ // applications with loopback off will not SEND the loopback packets to // other applications on the same host. See MSDN: http://goo.gl/6vqbj bool multicast_loopback_mode = true; + // Sets the OS send buffer size (in bytes) for the socket. This is the + // SO_SNDBUF socket option. This socket option matters less for UDP socket (as + // compared to TCP), because in theory all UDP data written to the kernel + // should directly go out to the network. The kernel usually doesn't need to + // buffer send data. Default value is 0, in which case, OS's default value + // will be used. + int32 send_buffer_size = 0; + // Sets the OS receive buffer size (in bytes) for the socket. This is the + // SO_RCVBUF socket option. The kernel allocates this much to hold the data + // arriving into this socket between the time when data arrives over the + // network and when it is read by UDPSocketReceiver. If buffer is full, + // new packets will be discarded. Default value is 0, in which case, OS's + // default value will be used. + int32 receive_buffer_size = 0; }; // UDPSocket is an interface that exposes UDP socket functionalities. @@ -43,58 +57,34 @@ // - Acquire a UDPSocket interface pointer and optionally supply a non-null // UDPSocketReceiverPtr. If consumers are not interested in received data, a // null UDPSocketReceiverPtr is acceptable. -// - Open(). -// - (optional) Set options. // - Use either Bind() or Connect() before datagrams can be sent or received. +// - (optional) Invoke setters (e.g. SetBroadcast()). // - Send / request to receive datagrams. Received datagrams will be delivered // to the bound receiver's OnReceived() call. // - Close the socket by destroying the interface pointer. interface UDPSocket { - // Opens the socket. This will request a socket of |address_family| from the - // OS and configure it with options specified in |socket_options|. If - // |socket_options| is null, default options will be used. Returns net::OK - // on success and a negative net error code on failure. After an error, caller - // may retry Open() with different options. - Open(net.interfaces.AddressFamily address_family, - UDPSocketOptions? socket_options) => (int32 result); - // Binds the address/port for this socket to |local_addr|. Caller can use port - // 0 to let the OS pick an available port. - // Should only be called after Open(). Returns net::OK and the real - // local address used on success and a negative net error code on failure. - Bind(net.interfaces.IPEndPoint local_addr) => - (int32 result, net.interfaces.IPEndPoint? local_addr_out); + // 0 to let the OS pick an available port. If |socket_options| is not null, + // configures the socket with the options before binding the socket. + // Returns net::OK and the real local address used on success and a negative + // net error code on failure. + Bind(net.interfaces.IPEndPoint local_addr, UDPSocketOptions? socket_options) + => (int32 result, net.interfaces.IPEndPoint? local_addr_out); // Connects the socket to |remote_addr|. This automatically binds the socket // to an available local port, so this cannot be used with Bind(). - // Should only be called after Open(). The address family of the local socket - // will be of the same net.interfaces.AddressFamily supplied during Open(). - // Returns net::OK and the local address of socket on success. Subsequent - // packets received will be from |remote_addr|. Returns a negative net error - // code on failure. - Connect(net.interfaces.IPEndPoint remote_addr) => + // If |socket_options| is not null, configures the socket with the options + // before connecting the socket. + // The address family of the local socket will be of the same + // net.interfaces.AddressFamily as |remote_addr|. Returns net::OK and the + // local address of socket on success. Subsequent packets received will be + // from |remote_addr|. Returns a negative net error code on failure. + Connect(net.interfaces.IPEndPoint remote_addr, + UDPSocketOptions? socket_options) => (int32 result, net.interfaces.IPEndPoint? local_addr_out); - // Sets the OS send buffer size (in bytes) for the socket. This is the - // SO_SNDBUF socket option. This socket option matters less for UDP socket (as - // compared to TCP), because in theory all UDP data written to the kernel - // should directly go out to the network. The kernel usually doesn't need to - // buffer send data. - // Should only be called after Open(). Returns net::OK upon success, and a - // net error code upon failure. - SetSendBufferSize(uint32 size) => (int32 result); - - // Sets the OS receive buffer size (in bytes) for the socket. This is the - // SO_RCVBUF socket option. The kernel allocates this much to hold the data - // arriving into this socket between the time when data arrives over the - // network and when it is read by UDPSocketReceiver. If buffer is full, - // new packets will be discarded. - // Should only be called after Open(). Returns net::OK upon success, and a - // net error code upon failure. - SetReceiveBufferSize(uint32 size) => (int32 result); - // Allows or disallows sending and receiving packets to and from broadcast - // addresses. Should only be called after Open(). Returns a net error code. + // addresses. Returns a net error code. Should only be called after Bind(). SetBroadcast(bool broadcast) => (int32 result); // Joins a multicast group. |group_address| is the group address to join, @@ -145,11 +135,19 @@ // // It is very likely that approach 1 will perform better than approach 2, // because in approach 2 getting every datagram takes at least the time of a - // round trip to the service side. - // TODO(xunjieli): Allow consumer to configure the underlying read buffer - // size. This is currently set to be 128KB, which is likely to be too big. + // round trip to the service side. Default buffer size of 64KiB will be + // allocated to receive each datagram. ReceiveMore(uint32 num_additional_datagrams); + // Same as ReceiveMore(), but with an ability to set the buffer size used for + // receiving each datagram. Note that |buffer_size| is the application-side + // buffer which is different from UDPSocketOptions::receive_buffer_size which + // is the OS-side buffer. |buffer_size| larger than 64KiB will be capped at + // 64KiB as the limit on data length of a IPv4 UDP packet is 65,507 and 65,535 + // for IPv6. + ReceiveMoreWithBufferSize( + uint32 num_additional_datagrams, uint32 buffer_size); + // Sends data to a particular destination, |dest_addr|. Should only be used // after Bind(). There is currently no limit on the size of |data|, other // than the restrictions on datagram size specified in the IP layer (e.g. @@ -172,6 +170,9 @@ Send(mojo.common.mojom.ReadOnlyBuffer data, MutableNetworkTrafficAnnotationTag traffic_annotation) => (int32 result); + + // Closes the socket. Connect() or Bind() can be used after Close(). + Close(); }; // An interface the consumers of UDPSocket can implement to listen for incoming
diff --git a/services/network/udp_socket.cc b/services/network/udp_socket.cc index f8484fb..4a19c98 100644 --- a/services/network/udp_socket.cc +++ b/services/network/udp_socket.cc
@@ -23,11 +23,10 @@ namespace { -// TODO(xunjieli): Default read buffer size is too big. Make it customizable. -const int kMaxReadSize = 64 * 1024; +const uint32_t kMaxReadSize = 64 * 1024; // The limit on data length for a UDP packet is 65,507 for IPv4 and 65,535 for // IPv6. -const int kMaxPacketSize = kMaxReadSize - 1; +const uint32_t kMaxPacketSize = kMaxReadSize - 1; class SocketWrapperImpl : public UDPSocket::SocketWrapper { public: @@ -38,20 +37,35 @@ : socket_(bind_type, rand_int_cb, net_log, source) {} ~SocketWrapperImpl() override {} - int Open(net::AddressFamily address_family) override { - return socket_.Open(address_family); + int Connect(const net::IPEndPoint& remote_addr, + mojom::UDPSocketOptionsPtr options, + net::IPEndPoint* local_addr_out) override { + int result = socket_.Open(remote_addr.GetFamily()); + if (result == net::OK) + result = ConfigureOptions(std::move(options)); + if (result == net::OK) + result = socket_.Connect(remote_addr); + if (result == net::OK) + result = socket_.GetLocalAddress(local_addr_out); + + if (result != net::OK) + socket_.Close(); + return result; } - int Connect(const net::IPEndPoint& remote_addr) override { - return socket_.Connect(remote_addr); - } - int Bind(const net::IPEndPoint& local_addr) override { - return socket_.Bind(local_addr); - } - int SetSendBufferSize(uint32_t size) override { - return socket_.SetSendBufferSize(size); - } - int SetReceiveBufferSize(uint32_t size) override { - return socket_.SetReceiveBufferSize(size); + int Bind(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, + net::IPEndPoint* local_addr_out) override { + int result = socket_.Open(local_addr.GetFamily()); + if (result == net::OK) + result = ConfigureOptions(std::move(options)); + if (result == net::OK) + result = socket_.Bind(local_addr); + if (result == net::OK) + result = socket_.GetLocalAddress(local_addr_out); + + if (result != net::OK) + socket_.Close(); + return result; } int SendTo( net::IOBuffer* buf, @@ -83,11 +97,11 @@ const net::CompletionCallback& callback) override { return socket_.RecvFrom(buf, buf_len, address, callback); } - int GetLocalAddress(net::IPEndPoint* address) const override { - return socket_.GetLocalAddress(address); - } - int ConfigureOptions(mojom::UDPSocketOptionsPtr options) override { + private: + int ConfigureOptions(mojom::UDPSocketOptionsPtr options) { + if (!options) + return net::OK; int result = net::OK; if (options->allow_address_reuse) result = socket_.AllowAddressReuse(); @@ -101,10 +115,17 @@ result = socket_.SetMulticastTimeToLive( base::saturated_cast<int32_t>(options->multicast_time_to_live)); } + if (result == net::OK && options->receive_buffer_size != 0) { + result = socket_.SetReceiveBufferSize( + base::saturated_cast<int32_t>(options->receive_buffer_size)); + } + if (result == net::OK && options->send_buffer_size != 0) { + result = socket_.SetSendBufferSize( + base::saturated_cast<int32_t>(options->send_buffer_size)); + } return result; } - private: net::UDPSocket socket_; DISALLOW_COPY_AND_ASSIGN(SocketWrapperImpl); @@ -118,8 +139,7 @@ UDPSocket::UDPSocket(mojom::UDPSocketRequest request, mojom::UDPSocketReceiverPtr receiver) - : is_opened_(false), - is_bound_(false), + : is_bound_(false), is_connected_(false), receiver_(std::move(receiver)), remaining_recv_slots_(0), @@ -133,95 +153,50 @@ binding_.set_connection_error_handler(std::move(handler)); } -void UDPSocket::Open(net::AddressFamily address_family, - mojom::UDPSocketOptionsPtr options, - OpenCallback callback) { - if (is_opened_) { - std::move(callback).Run(net::ERR_UNEXPECTED); +void UDPSocket::Connect(const net::IPEndPoint& remote_addr, + mojom::UDPSocketOptionsPtr options, + ConnectCallback callback) { + if (IsConnectedOrBound()) { + std::move(callback).Run(net::ERR_SOCKET_IS_CONNECTED, base::nullopt); return; } - wrapped_socket_ = std::make_unique<SocketWrapperImpl>( - net::DatagramSocket::RANDOM_BIND, base::BindRepeating(&base::RandInt), - nullptr, net::NetLogSource()); - int result = wrapped_socket_->Open(address_family); - if (result == net::OK && options) - result = wrapped_socket_->ConfigureOptions(std::move(options)); + DCHECK(!wrapped_socket_); + wrapped_socket_ = CreateSocketWrapper(); + net::IPEndPoint local_addr_out; + int result = wrapped_socket_->Connect(remote_addr, std::move(options), + &local_addr_out); if (result != net::OK) { wrapped_socket_.reset(); - } else { - is_opened_ = true; - } - std::move(callback).Run(result); -} - -void UDPSocket::Connect(const net::IPEndPoint& remote_addr, - ConnectCallback callback) { - net::IPEndPoint local_addr_out; - int result; - if (!is_opened_) { - result = net::ERR_UNEXPECTED; std::move(callback).Run(result, base::nullopt); return; } - if (IsConnectedOrBound()) { - result = net::ERR_SOCKET_IS_CONNECTED; - std::move(callback).Run(result, base::nullopt); - return; - } - result = wrapped_socket_->Connect(remote_addr); - if (result == net::OK) { - is_connected_ = true; - result = wrapped_socket_->GetLocalAddress(&local_addr_out); - } + is_connected_ = true; std::move(callback).Run(result, local_addr_out); } -void UDPSocket::Bind(const net::IPEndPoint& local_addr, BindCallback callback) { - net::IPEndPoint local_addr_out; - - int result; - if (!is_opened_) { - result = net::ERR_UNEXPECTED; - std::move(callback).Run(result, base::nullopt); - return; - } +void UDPSocket::Bind(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, + BindCallback callback) { if (IsConnectedOrBound()) { - result = net::ERR_SOCKET_IS_CONNECTED; + std::move(callback).Run(net::ERR_SOCKET_IS_CONNECTED, base::nullopt); + return; + } + DCHECK(!wrapped_socket_); + wrapped_socket_ = CreateSocketWrapper(); + net::IPEndPoint local_addr_out; + int result = + wrapped_socket_->Bind(local_addr, std::move(options), &local_addr_out); + if (result != net::OK) { + wrapped_socket_.reset(); std::move(callback).Run(result, base::nullopt); return; } - result = wrapped_socket_->Bind(local_addr); - if (result == net::OK) { - is_bound_ = true; - result = wrapped_socket_->GetLocalAddress(&local_addr_out); - } - std::move(callback).Run(result, base::make_optional(local_addr_out)); -} - -void UDPSocket::SetSendBufferSize(uint32_t size, - SetSendBufferSizeCallback callback) { - if (!is_opened_) { - std::move(callback).Run(net::ERR_UNEXPECTED); - return; - } - int net_result = - wrapped_socket_->SetSendBufferSize(base::saturated_cast<int32_t>(size)); - std::move(callback).Run(net_result); -} - -void UDPSocket::SetReceiveBufferSize(uint32_t size, - SetReceiveBufferSizeCallback callback) { - if (!is_opened_) { - std::move(callback).Run(net::ERR_UNEXPECTED); - return; - } - int net_result = wrapped_socket_->SetReceiveBufferSize( - base::saturated_cast<int32_t>(size)); - std::move(callback).Run(net_result); + is_bound_ = true; + std::move(callback).Run(result, local_addr_out); } void UDPSocket::SetBroadcast(bool broadcast, SetBroadcastCallback callback) { - if (!is_opened_) { + if (!is_bound_) { std::move(callback).Run(net::ERR_UNEXPECTED); return; } @@ -250,6 +225,11 @@ } void UDPSocket::ReceiveMore(uint32_t num_additional_datagrams) { + ReceiveMoreWithBufferSize(num_additional_datagrams, kMaxReadSize); +} + +void UDPSocket::ReceiveMoreWithBufferSize(uint32_t num_additional_datagrams, + uint32_t buffer_size) { if (!receiver_) return; if (!IsConnectedOrBound()) { @@ -265,7 +245,7 @@ } if (!recvfrom_buffer_) { DCHECK_EQ(num_additional_datagrams, remaining_recv_slots_); - DoRecvFrom(); + DoRecvFrom(std::min(buffer_size, kMaxReadSize)); } } @@ -298,24 +278,45 @@ std::move(callback)); } +void UDPSocket::Close() { + if (!IsConnectedOrBound()) { + return; + } + is_connected_ = false; + is_bound_ = false; + recvfrom_buffer_ = nullptr; + send_callback_.Reset(); + send_buffer_ = nullptr; + remaining_recv_slots_ = 0; + wrapped_socket_.reset(); +} + +std::unique_ptr<UDPSocket::SocketWrapper> UDPSocket::CreateSocketWrapper() + const { + return std::make_unique<SocketWrapperImpl>( + net::DatagramSocket::RANDOM_BIND, base::BindRepeating(&base::RandInt), + nullptr, net::NetLogSource()); +} + bool UDPSocket::IsConnectedOrBound() const { return is_connected_ || is_bound_; } -void UDPSocket::DoRecvFrom() { +void UDPSocket::DoRecvFrom(uint32_t buffer_size) { DCHECK(receiver_); DCHECK(!recvfrom_buffer_); DCHECK_GT(remaining_recv_slots_, 0u); + DCHECK_GE(kMaxReadSize, buffer_size); - recvfrom_buffer_ = new net::IOBuffer(kMaxReadSize); + recvfrom_buffer_ = new net::IOBuffer(static_cast<size_t>(buffer_size)); // base::Unretained(this) is safe because socket is owned by |this|. int net_result = wrapped_socket_->RecvFrom( - recvfrom_buffer_.get(), kMaxReadSize, &recvfrom_address_, + recvfrom_buffer_.get(), buffer_size, &recvfrom_address_, base::BindRepeating(&UDPSocket::OnRecvFromCompleted, - base::Unretained(this))); + base::Unretained(this), buffer_size)); if (net_result != net::ERR_IO_PENDING) - OnRecvFromCompleted(net_result); + OnRecvFromCompleted(buffer_size, net_result); } void UDPSocket::DoSendToOrWrite( @@ -384,7 +385,7 @@ OnSendToCompleted(net_result); } -void UDPSocket::OnRecvFromCompleted(int net_result) { +void UDPSocket::OnRecvFromCompleted(uint32_t buffer_size, int net_result) { DCHECK(recvfrom_buffer_); if (net_result >= 0) { @@ -401,7 +402,7 @@ DCHECK_GT(remaining_recv_slots_, 0u); remaining_recv_slots_--; if (remaining_recv_slots_ > 0) - DoRecvFrom(); + DoRecvFrom(buffer_size); } void UDPSocket::OnSendToCompleted(int net_result) {
diff --git a/services/network/udp_socket.h b/services/network/udp_socket.h index 814ce959..29e4116 100644 --- a/services/network/udp_socket.h +++ b/services/network/udp_socket.h
@@ -41,14 +41,15 @@ class SocketWrapper { public: virtual ~SocketWrapper() {} - // This wrapper class forwards the functions to an concrete udp socket + // This wrapper class forwards the functions to a concrete udp socket // implementation. Please refer to udp_socket_posix.h/udp_socket_win.h for // definitions. - virtual int Open(net::AddressFamily address_family) = 0; - virtual int Connect(const net::IPEndPoint& remote_addr) = 0; - virtual int Bind(const net::IPEndPoint& local_addr) = 0; - virtual int SetSendBufferSize(uint32_t size) = 0; - virtual int SetReceiveBufferSize(uint32_t size) = 0; + virtual int Connect(const net::IPEndPoint& remote_addr, + mojom::UDPSocketOptionsPtr options, + net::IPEndPoint* local_addr_out) = 0; + virtual int Bind(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, + net::IPEndPoint* local_addr_out) = 0; virtual int SendTo( net::IOBuffer* buf, int buf_len, @@ -67,12 +68,6 @@ int buf_len, net::IPEndPoint* address, const net::CompletionCallback& callback) = 0; - virtual int GetLocalAddress(net::IPEndPoint* address) const = 0; - - // Configures the socket with socket options specified in |options|. This - // needs to be called after Open() and before Bind()/Connect(). - // Returns a net error code. - virtual int ConfigureOptions(mojom::UDPSocketOptionsPtr options) = 0; }; UDPSocket(mojom::UDPSocketRequest request, @@ -83,22 +78,20 @@ void set_connection_error_handler(base::OnceClosure handler); // UDPSocket implementation. - void Open(net::AddressFamily address_family, - mojom::UDPSocketOptionsPtr options, - OpenCallback callback) override; void Connect(const net::IPEndPoint& remote_addr, + mojom::UDPSocketOptionsPtr options, ConnectCallback callback) override; - void Bind(const net::IPEndPoint& local_addr, BindCallback callback) override; - void SetSendBufferSize(uint32_t size, - SetSendBufferSizeCallback callback) override; - void SetReceiveBufferSize(uint32_t size, - SetReceiveBufferSizeCallback callback) override; + void Bind(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, + BindCallback callback) override; void SetBroadcast(bool broadcast, SetBroadcastCallback callback) override; void JoinGroup(const net::IPAddress& group_address, JoinGroupCallback callback) override; void LeaveGroup(const net::IPAddress& group_address, LeaveGroupCallback callback) override; void ReceiveMore(uint32_t num_additional_datagrams) override; + void ReceiveMoreWithBufferSize(uint32_t num_additional_datagrams, + uint32_t buffer_size) override; void SendTo(const net::IPEndPoint& dest_addr, base::span<const uint8_t> data, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, @@ -106,6 +99,7 @@ void Send(base::span<const uint8_t> data, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, SendCallback callback) override; + void Close() override; private: friend class UDPSocketTest; @@ -122,10 +116,13 @@ SendToCallback callback; }; + // Helper method to create a new SocketWrapper. + std::unique_ptr<UDPSocket::SocketWrapper> CreateSocketWrapper() const; + // Returns whether a successful Connect() or Bind() has been executed. bool IsConnectedOrBound() const; - void DoRecvFrom(); + void DoRecvFrom(uint32_t buffer_size); void DoSendToOrWrite( const net::IPEndPoint* dest_addr, const base::span<const uint8_t>& data, @@ -137,12 +134,9 @@ const net::NetworkTrafficAnnotationTag& traffic_annotation, SendToCallback callback); - void OnRecvFromCompleted(int net_result); + void OnRecvFromCompleted(uint32_t buffer_size, int net_result); void OnSendToCompleted(int net_result); - // Whether an Open() has been successfully executed. - bool is_opened_; - // Whether a Bind() has been successfully executed. bool is_bound_;
diff --git a/services/network/udp_socket_test_util.cc b/services/network/udp_socket_test_util.cc index 2a4a38f..881ab86 100644 --- a/services/network/udp_socket_test_util.cc +++ b/services/network/udp_socket_test_util.cc
@@ -19,34 +19,13 @@ UDPSocketTestHelper::~UDPSocketTestHelper() {} -int UDPSocketTestHelper::OpenSync(net::AddressFamily address_family) { - mojom::UDPSocketOptionsPtr options; - return OpenWithOptionsSync(address_family, std::move(options)); -} - -int UDPSocketTestHelper::OpenWithOptionsSync( - net::AddressFamily address_family, - mojom::UDPSocketOptionsPtr options) { - base::RunLoop run_loop; - int net_error = net::ERR_FAILED; - socket_->get()->Open( - address_family, std::move(options), - base::BindOnce( - [](base::RunLoop* run_loop, int* result_out, int result) { - *result_out = result; - run_loop->Quit(); - }, - base::Unretained(&run_loop), base::Unretained(&net_error))); - run_loop.Run(); - return net_error; -} - int UDPSocketTestHelper::ConnectSync(const net::IPEndPoint& remote_addr, + mojom::UDPSocketOptionsPtr options, net::IPEndPoint* local_addr_out) { base::RunLoop run_loop; int net_error = net::ERR_FAILED; socket_->get()->Connect( - remote_addr, + remote_addr, std::move(options), base::BindOnce( [](base::RunLoop* run_loop, int* result_out, net::IPEndPoint* local_addr_out, int result, @@ -64,22 +43,24 @@ } int UDPSocketTestHelper::BindSync(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, net::IPEndPoint* local_addr_out) { base::RunLoop run_loop; int net_error = net::ERR_FAILED; socket_->get()->Bind( - local_addr, base::BindOnce( - [](base::RunLoop* run_loop, int* result_out, - net::IPEndPoint* local_addr_out, int result, - const base::Optional<net::IPEndPoint>& local_addr) { - *result_out = result; - if (local_addr) { - *local_addr_out = local_addr.value(); - } - run_loop->Quit(); - }, - base::Unretained(&run_loop), base::Unretained(&net_error), - base::Unretained(local_addr_out))); + local_addr, std::move(options), + base::BindOnce( + [](base::RunLoop* run_loop, int* result_out, + net::IPEndPoint* local_addr_out, int result, + const base::Optional<net::IPEndPoint>& local_addr) { + *result_out = result; + if (local_addr) { + *local_addr_out = local_addr.value(); + } + run_loop->Quit(); + }, + base::Unretained(&run_loop), base::Unretained(&net_error), + base::Unretained(local_addr_out))); run_loop.Run(); return net_error; } @@ -117,30 +98,17 @@ return net_error; } -int UDPSocketTestHelper::SetSendBufferSizeSync(size_t size) { +int UDPSocketTestHelper::SetBroadcastSync(bool broadcast) { base::RunLoop run_loop; int net_error = net::ERR_FAILED; - socket_->get()->SetSendBufferSize( - size, base::BindOnce( - [](base::RunLoop* run_loop, int* result_out, int result) { - *result_out = result; - run_loop->Quit(); - }, - base::Unretained(&run_loop), base::Unretained(&net_error))); - run_loop.Run(); - return net_error; -} - -int UDPSocketTestHelper::SetReceiveBufferSizeSync(size_t size) { - base::RunLoop run_loop; - int net_error = net::ERR_FAILED; - socket_->get()->SetReceiveBufferSize( - size, base::BindOnce( - [](base::RunLoop* run_loop, int* result_out, int result) { - *result_out = result; - run_loop->Quit(); - }, - base::Unretained(&run_loop), base::Unretained(&net_error))); + socket_->get()->SetBroadcast( + broadcast, + base::BindOnce( + [](base::RunLoop* run_loop, int* result_out, int result) { + *result_out = result; + run_loop->Quit(); + }, + base::Unretained(&run_loop), base::Unretained(&net_error))); run_loop.Run(); return net_error; }
diff --git a/services/network/udp_socket_test_util.h b/services/network/udp_socket_test_util.h index 30cca80..5f25001 100644 --- a/services/network/udp_socket_test_util.h +++ b/services/network/udp_socket_test_util.h
@@ -28,18 +28,16 @@ public: explicit UDPSocketTestHelper(mojom::UDPSocketPtr* socket); ~UDPSocketTestHelper(); - int OpenSync(net::AddressFamily address_family); - int OpenWithOptionsSync(net::AddressFamily address_family, - mojom::UDPSocketOptionsPtr options); int ConnectSync(const net::IPEndPoint& remote_addr, + mojom::UDPSocketOptionsPtr options, net::IPEndPoint* local_addr_out); int BindSync(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, net::IPEndPoint* local_addr_out); int SendToSync(const net::IPEndPoint& remote_addr, const std::vector<uint8_t>& input); int SendSync(const std::vector<uint8_t>& input); - int SetSendBufferSizeSync(size_t size); - int SetReceiveBufferSizeSync(size_t size); + int SetBroadcastSync(bool broadcast); int JoinGroupSync(const net::IPAddress& group_address); int LeaveGroupSync(const net::IPAddress& group_address);
diff --git a/services/network/udp_socket_unittest.cc b/services/network/udp_socket_unittest.cc index b4ed79b..050ad589c5 100644 --- a/services/network/udp_socket_unittest.cc +++ b/services/network/udp_socket_unittest.cc
@@ -35,23 +35,15 @@ SocketWrapperTestImpl() {} ~SocketWrapperTestImpl() override {} - int Open(net::AddressFamily address_family) override { + int Connect(const net::IPEndPoint& remote_addr, + mojom::UDPSocketOptionsPtr options, + net::IPEndPoint* local_addr_out) override { NOTREACHED(); return net::ERR_NOT_IMPLEMENTED; } - int Connect(const net::IPEndPoint& remote_addr) override { - NOTREACHED(); - return net::ERR_NOT_IMPLEMENTED; - } - int Bind(const net::IPEndPoint& local_addr) override { - NOTREACHED(); - return net::ERR_NOT_IMPLEMENTED; - } - int SetSendBufferSize(uint32_t size) override { - NOTREACHED(); - return net::ERR_NOT_IMPLEMENTED; - } - int SetReceiveBufferSize(uint32_t size) override { + int Bind(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, + net::IPEndPoint* local_addr_out) override { NOTREACHED(); return net::ERR_NOT_IMPLEMENTED; } @@ -91,14 +83,6 @@ NOTREACHED(); return net::ERR_NOT_IMPLEMENTED; } - int GetLocalAddress(net::IPEndPoint* address) const override { - NOTREACHED(); - return net::ERR_NOT_IMPLEMENTED; - } - int ConfigureOptions(mojom::UDPSocketOptionsPtr options) override { - NOTREACHED(); - return net::ERR_NOT_IMPLEMENTED; - } private: DISALLOW_COPY_AND_ASSIGN(SocketWrapperTestImpl); @@ -121,8 +105,11 @@ HangingUDPSocket() {} // SocketWrapperTestImpl implementation. - int Open(net::AddressFamily address_family) override { return net::OK; } - int Bind(const net::IPEndPoint& local_addr) override { return net::OK; } + int Bind(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, + net::IPEndPoint* local_addr_out) override { + return net::OK; + } int SendTo( net::IOBuffer* buf, int buf_len, @@ -138,10 +125,6 @@ pending_send_requests_.push_back(callback); return net::ERR_IO_PENDING; } - int GetLocalAddress(net::IPEndPoint* address) const override { - *address = GetLocalHostWithAnyPort(); - return net::OK; - } void set_expected_data(std::vector<uint8_t> expected_data) { expected_data_ = expected_data; @@ -176,8 +159,11 @@ class ZeroByteReadUDPSocket : public SocketWrapperTestImpl { public: ZeroByteReadUDPSocket() {} - int Open(net::AddressFamily address_family) override { return net::OK; } - int Bind(const net::IPEndPoint& local_addr) override { return net::OK; } + int Bind(const net::IPEndPoint& local_addr, + mojom::UDPSocketOptionsPtr options, + net::IPEndPoint* local_addr_out) override { + return net::OK; + } int RecvFrom(net::IOBuffer* buf, int buf_len, net::IPEndPoint* address, @@ -185,10 +171,6 @@ *address = GetLocalHostWithAnyPort(); return 0; } - int GetLocalAddress(net::IPEndPoint* address) const override { - *address = GetLocalHostWithAnyPort(); - return net::OK; - } }; } // namespace @@ -217,36 +199,32 @@ }; TEST_F(UDPSocketTest, Settings) { - mojom::UDPSocketReceiverPtr receiver_interface_ptr; mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), - std::move(receiver_interface_ptr)); + UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); net::IPEndPoint server_addr; net::IPEndPoint any_port(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&socket_ptr); - ASSERT_EQ(net::OK, helper.OpenSync(any_port.GetFamily())); net::IPEndPoint local_addr; - ASSERT_EQ(net::OK, helper.BindSync(any_port, &local_addr)); + mojom::UDPSocketOptionsPtr options = network::mojom::UDPSocketOptions::New(); + options->send_buffer_size = 1024; + options->receive_buffer_size = 2048; + ASSERT_EQ(net::OK, + helper.BindSync(any_port, std::move(options), &local_addr)); EXPECT_NE(local_addr.ToString(), any_port.ToString()); - EXPECT_EQ(net::OK, helper.SetSendBufferSizeSync(1024)); - EXPECT_EQ(net::OK, helper.SetReceiveBufferSizeSync(2048)); } // Tests that Send() is used after Bind() is not supported. Send() should only // be used after Connect(). TEST_F(UDPSocketTest, TestSendWithBind) { - mojom::UDPSocketReceiverPtr receiver_interface_ptr; mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), - std::move(receiver_interface_ptr)); + UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); // Bind() the socket. test::UDPSocketTestHelper helper(&socket_ptr); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); // Connect() has not been used, so Send() is not supported. std::vector<uint8_t> test_msg{1}; @@ -269,75 +247,55 @@ net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); // Create a client socket to send datagrams. - mojom::UDPSocketReceiverPtr client_receiver_ptr; mojom::UDPSocketPtr client_socket; - UDPSocket client_impl(mojo::MakeRequest(&client_socket), - std::move(client_receiver_ptr)); + UDPSocket client_impl(mojo::MakeRequest(&client_socket), nullptr); net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper client_helper(&client_socket); - ASSERT_EQ(net::OK, client_helper.OpenSync(client_addr.GetFamily())); - ASSERT_EQ(net::OK, client_helper.ConnectSync(server_addr, &client_addr)); + ASSERT_EQ(net::OK, + client_helper.ConnectSync(server_addr, nullptr, &client_addr)); std::vector<uint8_t> test_msg({1}); int result = client_helper.SendToSync(server_addr, test_msg); EXPECT_EQ(net::ERR_UNEXPECTED, result); } -// Tests that the sequence of calling Open(), Bind()/Connect() and setters is +// Tests that the sequence of calling Bind()/Connect() and setters is // important. TEST_F(UDPSocketTest, TestUnexpectedSequences) { - mojom::UDPSocketReceiverPtr receiver_interface_ptr; mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), - std::move(receiver_interface_ptr)); - net::IPEndPoint server_addr; - net::IPEndPoint any_port(GetLocalHostWithAnyPort()); - - // Before Open(), calling Connect() or Bind() will result in an error. - net::IPEndPoint local_addr; + UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); test::UDPSocketTestHelper helper(&socket_ptr); - ASSERT_EQ(net::ERR_UNEXPECTED, helper.BindSync(any_port, &local_addr)); - ASSERT_EQ(net::ERR_UNEXPECTED, helper.ConnectSync(any_port, &local_addr)); + net::IPEndPoint local_addr(GetLocalHostWithAnyPort()); - // Calling any Setters that depend on Open() should fail. - EXPECT_EQ(net::ERR_UNEXPECTED, helper.SetSendBufferSizeSync(1024)); - EXPECT_EQ(net::ERR_UNEXPECTED, helper.SetReceiveBufferSizeSync(2048)); - - // Now call Open(). - ASSERT_EQ(net::OK, helper.OpenSync(any_port.GetFamily())); - EXPECT_NE(local_addr.ToString(), any_port.ToString()); - - // It is illegal call Open() twice. - ASSERT_EQ(net::ERR_UNEXPECTED, helper.OpenSync(any_port.GetFamily())); - - // Now these Setters should work. - EXPECT_EQ(net::OK, helper.SetSendBufferSizeSync(1024)); - EXPECT_EQ(net::OK, helper.SetReceiveBufferSizeSync(2048)); + // Now these Setters should not work before Bind(). + EXPECT_EQ(net::ERR_UNEXPECTED, helper.SetBroadcastSync(true)); // Now Bind() the socket. - ASSERT_EQ(net::OK, helper.BindSync(any_port, &local_addr)); + ASSERT_EQ(net::OK, helper.BindSync(local_addr, nullptr, &local_addr)); // Calling Connect() after Bind() should fail because they can't be both used. ASSERT_EQ(net::ERR_SOCKET_IS_CONNECTED, - helper.ConnectSync(any_port, &local_addr)); + helper.ConnectSync(local_addr, nullptr, &local_addr)); + + // Now Close() the socket. + socket_ptr->Close(); + + // Re-Bind() is okay. + ASSERT_EQ(net::OK, helper.BindSync(local_addr, nullptr, &local_addr)); } // Tests that if the underlying socket implementation's Send() returned // ERR_IO_PENDING, udp_socket.cc doesn't free the send buffer. TEST_F(UDPSocketTest, TestBufferValid) { - mojom::UDPSocketReceiverPtr receiver_interface_ptr; mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), - std::move(receiver_interface_ptr)); + UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&socket_ptr); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); HangingUDPSocket* socket_raw_ptr = new HangingUDPSocket(); SetWrappedSocket(&impl, base::WrapUnique(socket_raw_ptr)); @@ -370,17 +328,14 @@ // Test that exercises the queuing of send requests and makes sure // ERR_INSUFFICIENT_RESOURCES is returned appropriately. TEST_F(UDPSocketTest, TestInsufficientResources) { - mojom::UDPSocketReceiverPtr receiver_interface_ptr; mojom::UDPSocketPtr socket_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), - std::move(receiver_interface_ptr)); + UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); const size_t kQueueSize = UDPSocket::kMaxPendingSendRequests; net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&socket_ptr); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); HangingUDPSocket* socket_raw_ptr = new HangingUDPSocket(); SetWrappedSocket(&impl, base::WrapUnique(socket_raw_ptr)); @@ -426,8 +381,7 @@ net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); server_socket->ReceiveMore(std::numeric_limits<uint32_t>::max()); server_socket.FlushForTesting(); @@ -450,18 +404,15 @@ net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); // Create a client socket to send datagrams. - mojom::UDPSocketReceiverPtr client_receiver_ptr; mojom::UDPSocketPtr client_socket; - UDPSocket client_impl(mojo::MakeRequest(&client_socket), - std::move(client_receiver_ptr)); + UDPSocket client_impl(mojo::MakeRequest(&client_socket), nullptr); net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper client_helper(&client_socket); - ASSERT_EQ(net::OK, client_helper.OpenSync(client_addr.GetFamily())); - ASSERT_EQ(net::OK, client_helper.ConnectSync(server_addr, &client_addr)); + ASSERT_EQ(net::OK, + client_helper.ConnectSync(server_addr, nullptr, &client_addr)); const size_t kDatagramCount = 6; server_socket->ReceiveMore(kDatagramCount); @@ -488,18 +439,35 @@ // results in an early rejection. std::vector<uint8_t> large_msg(64 * 1024, 1); EXPECT_EQ(net::ERR_MSG_TOO_BIG, helper.SendToSync(client_addr, large_msg)); + + // Close and re-Connect client socket. + client_socket->Close(); + client_socket.FlushForTesting(); + + // Make sure datagram can still be sent from the re-connected client socket. + ASSERT_EQ(net::OK, + client_helper.ConnectSync(server_addr, nullptr, &client_addr)); + server_socket->ReceiveMore(1); + std::vector<uint8_t> msg(CreateTestMessage(0, kDatagramSize)); + EXPECT_EQ(net::OK, client_helper.SendSync(msg)); + + receiver.WaitForReceivedResults(kDatagramCount + 1); + ASSERT_EQ(kDatagramCount + 1, receiver.results().size()); + + auto result = receiver.results()[kDatagramCount]; + EXPECT_EQ(net::OK, result.net_error); + EXPECT_EQ(result.src_addr, client_addr); + EXPECT_EQ(msg, result.data.value()); } TEST_F(UDPSocketTest, TestReadSendTo) { // Create a server socket to send data. mojom::UDPSocketPtr server_socket; - mojom::UDPSocketReceiverPtr receiver_ptr; - UDPSocket impl(mojo::MakeRequest(&server_socket), std::move(receiver_ptr)); + UDPSocket impl(mojo::MakeRequest(&server_socket), nullptr); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); // Create a client socket to send datagrams. test::UDPSocketReceiverImpl receiver; @@ -512,8 +480,8 @@ std::move(client_receiver_ptr)); net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper client_helper(&client_socket); - ASSERT_EQ(net::OK, client_helper.OpenSync(client_addr.GetFamily())); - ASSERT_EQ(net::OK, client_helper.ConnectSync(server_addr, &client_addr)); + ASSERT_EQ(net::OK, + client_helper.ConnectSync(server_addr, nullptr, &client_addr)); const size_t kDatagramCount = 6; client_socket->ReceiveMore(kDatagramCount); @@ -541,20 +509,81 @@ // results in an early rejection. std::vector<uint8_t> large_msg(64 * 1024, 1); EXPECT_EQ(net::ERR_MSG_TOO_BIG, helper.SendToSync(client_addr, large_msg)); + + // Make sure datagram can still be sent from the re-bound server socket. + server_socket->Close(); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); + client_socket->ReceiveMore(1); + std::vector<uint8_t> msg(CreateTestMessage(0, kDatagramSize)); + EXPECT_EQ(net::OK, helper.SendToSync(client_addr, msg)); + + receiver.WaitForReceivedResults(kDatagramCount + 1); + ASSERT_EQ(kDatagramCount + 1, receiver.results().size()); + + auto result = receiver.results()[kDatagramCount]; + EXPECT_EQ(net::OK, result.net_error); + EXPECT_FALSE(result.src_addr); + EXPECT_EQ(msg, result.data.value()); } -// Make sure passing an invalid net::IPEndPoint will be detected by -// serialization/deserialization in mojo. -TEST_F(UDPSocketTest, TestSendToInvalidAddress) { +TEST_F(UDPSocketTest, TestReceiveMoreWithBufferSize) { + // Create a server socket to listen for incoming datagrams. + test::UDPSocketReceiverImpl receiver; + mojo::Binding<mojom::UDPSocketReceiver> receiver_binding(&receiver); mojom::UDPSocketReceiverPtr receiver_interface_ptr; + receiver_binding.Bind(mojo::MakeRequest(&receiver_interface_ptr)); + mojom::UDPSocketPtr server_socket; UDPSocket impl(mojo::MakeRequest(&server_socket), std::move(receiver_interface_ptr)); net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&server_socket); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); + + // Create a client socket to send datagrams. + mojom::UDPSocketPtr client_socket; + UDPSocket client_impl(mojo::MakeRequest(&client_socket), nullptr); + net::IPEndPoint client_addr(GetLocalHostWithAnyPort()); + test::UDPSocketTestHelper client_helper(&client_socket); + ASSERT_EQ(net::OK, + client_helper.ConnectSync(server_addr, nullptr, &client_addr)); + + // Use a buffer size that is 1 byte smaller than the datagram size. + // This should result in net::ERR_MSG_TOO_BIG, because the transport can't + // complete the read with this small buffer size. + size_t buffer_size = kDatagramSize - 1; + server_socket->ReceiveMoreWithBufferSize(1, buffer_size); + std::vector<uint8_t> test_msg(CreateTestMessage(0, kDatagramSize)); + ASSERT_EQ(net::OK, client_helper.SendSync(test_msg)); + + receiver.WaitForReceivedResults(1); + ASSERT_EQ(1u, receiver.results().size()); + auto result = receiver.results()[0]; + EXPECT_EQ(net::ERR_MSG_TOO_BIG, result.net_error); + EXPECT_FALSE(result.data); + + // Now use a buffer size that is equal to datagram size. This should be okay. + server_socket->ReceiveMoreWithBufferSize(1, kDatagramSize); + ASSERT_EQ(net::OK, client_helper.SendSync(test_msg)); + + receiver.WaitForReceivedResults(2); + ASSERT_EQ(2u, receiver.results().size()); + result = receiver.results()[1]; + EXPECT_EQ(net::OK, result.net_error); + EXPECT_EQ(client_addr, result.src_addr.value()); + EXPECT_EQ(test_msg, result.data.value()); +} + +// Make sure passing an invalid net::IPEndPoint will be detected by +// serialization/deserialization in mojo. +TEST_F(UDPSocketTest, TestSendToInvalidAddress) { + mojom::UDPSocketPtr server_socket; + UDPSocket impl(mojo::MakeRequest(&server_socket), nullptr); + + net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); + test::UDPSocketTestHelper helper(&server_socket); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); std::vector<uint8_t> test_msg{1}; std::vector<uint8_t> invalid_ip_addr{127, 0, 0, 0, 1}; @@ -587,8 +616,7 @@ net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); test::UDPSocketTestHelper helper(&socket_ptr); - ASSERT_EQ(net::OK, helper.OpenSync(server_addr.GetFamily())); - ASSERT_EQ(net::OK, helper.BindSync(server_addr, &server_addr)); + ASSERT_EQ(net::OK, helper.BindSync(server_addr, nullptr, &server_addr)); SetWrappedSocket(&impl, std::make_unique<ZeroByteReadUDPSocket>()); @@ -636,9 +664,7 @@ net::IPAddress bind_ip_address; EXPECT_TRUE(bind_ip_address.AssignFromIPLiteral("0.0.0.0")); net::IPEndPoint socket_address(bind_ip_address, 0); - ASSERT_EQ(net::OK, helper.OpenWithOptionsSync(socket_address.GetFamily(), - std::move(options))); - ASSERT_EQ(net::OK, helper.BindSync(socket_address, &socket_address)); + ASSERT_EQ(net::OK, helper.BindSync(socket_address, nullptr, &socket_address)); int port = socket_address.port(); EXPECT_NE(0, port); EXPECT_EQ(net::OK, helper.JoinGroupSync(group_ip)); @@ -659,15 +685,12 @@ // Create a second socket to send a packet to multicast group. mojom::UDPSocketPtr second_socket_ptr; - mojom::UDPSocketReceiverPtr second_receiver_ptr; - UDPSocket second_socket_impl(mojo::MakeRequest(&second_socket_ptr), - std::move(second_receiver_ptr)); + UDPSocket second_socket_impl(mojo::MakeRequest(&second_socket_ptr), nullptr); test::UDPSocketTestHelper second_socket_helper(&second_socket_ptr); net::IPEndPoint second_socket_address(bind_ip_address, 0); - ASSERT_EQ(net::OK, second_socket_helper.OpenWithOptionsSync( - second_socket_address.GetFamily(), nullptr)); - ASSERT_EQ(net::OK, second_socket_helper.BindSync(second_socket_address, - &second_socket_address)); + ASSERT_EQ(net::OK, + second_socket_helper.BindSync(second_socket_address, nullptr, + &second_socket_address)); int second_port = second_socket_address.port(); ASSERT_EQ(net::OK, second_socket_helper.SendToSync(group_alias, test_msg)); @@ -693,26 +716,32 @@ } TEST_F(UDPSocketTest, ErrorHappensDuringSocketOptionsConfiguration) { - mojom::UDPSocketPtr socket_ptr; - mojom::UDPSocketReceiverPtr receiver_ptr; - UDPSocket impl(mojo::MakeRequest(&socket_ptr), std::move(receiver_ptr)); + mojom::UDPSocketPtr server_socket_ptr; + UDPSocket server_impl(mojo::MakeRequest(&server_socket_ptr), nullptr); + test::UDPSocketTestHelper server_helper(&server_socket_ptr); + net::IPEndPoint server_addr(GetLocalHostWithAnyPort()); + ASSERT_EQ(net::OK, + server_helper.BindSync(server_addr, nullptr, &server_addr)); + mojom::UDPSocketPtr socket_ptr; + UDPSocket impl(mojo::MakeRequest(&socket_ptr), nullptr); test::UDPSocketTestHelper helper(&socket_ptr); // Invalid options. mojom::UDPSocketOptionsPtr options = network::mojom::UDPSocketOptions::New(); options->multicast_time_to_live = 256; - ASSERT_EQ( - net::ERR_INVALID_ARGUMENT, - helper.OpenWithOptionsSync(net::ADDRESS_FAMILY_IPV4, std::move(options))); + net::IPEndPoint local_addr; + ASSERT_EQ(net::ERR_INVALID_ARGUMENT, + helper.ConnectSync(server_addr, std::move(options), &local_addr)); - // It's legal to retry Open() with valid options. + // It's legal to retry Connect() with valid options. mojom::UDPSocketOptionsPtr valid_options = network::mojom::UDPSocketOptions::New(); valid_options->multicast_time_to_live = 255; - ASSERT_EQ(net::OK, helper.OpenWithOptionsSync(net::ADDRESS_FAMILY_IPV4, - std::move(options))); + ASSERT_EQ(net::OK, + helper.ConnectSync(server_addr, std::move(options), &local_addr)); + EXPECT_NE(0, local_addr.port()); } } // namespace network
diff --git a/services/network/network_service_url_loader_factory.cc b/services/network/url_loader_factory.cc similarity index 84% rename from services/network/network_service_url_loader_factory.cc rename to services/network/url_loader_factory.cc index 1e91f4ae..ff6b70bdd 100644 --- a/services/network/network_service_url_loader_factory.cc +++ b/services/network/url_loader_factory.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "services/network/network_service_url_loader_factory.h" +#include "services/network/url_loader_factory.h" #include "base/logging.h" #include "services/network/network_context.h" @@ -12,9 +12,7 @@ namespace network { -NetworkServiceURLLoaderFactory::NetworkServiceURLLoaderFactory( - NetworkContext* context, - uint32_t process_id) +URLLoaderFactory::URLLoaderFactory(NetworkContext* context, uint32_t process_id) : context_(context), process_id_(process_id) { if (context_->network_service()) { context->network_service()->keepalive_statistics_recorder()->Register( @@ -22,14 +20,14 @@ } } -NetworkServiceURLLoaderFactory::~NetworkServiceURLLoaderFactory() { +URLLoaderFactory::~URLLoaderFactory() { if (context_->network_service()) { context_->network_service()->keepalive_statistics_recorder()->Unregister( process_id_); } } -void NetworkServiceURLLoaderFactory::CreateLoaderAndStart( +void URLLoaderFactory::CreateLoaderAndStart( mojom::URLLoaderRequest request, int32_t routing_id, int32_t request_id, @@ -61,8 +59,7 @@ process_id_, std::move(keepalive_statistics_recorder)); } -void NetworkServiceURLLoaderFactory::Clone( - mojom::URLLoaderFactoryRequest request) { +void URLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) { context_->CreateURLLoaderFactory(std::move(request), process_id_); }
diff --git a/services/network/network_service_url_loader_factory.h b/services/network/url_loader_factory.h similarity index 72% rename from services/network/network_service_url_loader_factory.h rename to services/network/url_loader_factory.h index db319c6..cb79099 100644 --- a/services/network/network_service_url_loader_factory.h +++ b/services/network/url_loader_factory.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SERVICES_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_H_ -#define SERVICES_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_H_ +#ifndef SERVICES_NETWORK_URL_LOADER_FACTORY_H_ +#define SERVICES_NETWORK_URL_LOADER_FACTORY_H_ #include "base/macros.h" #include "net/traffic_annotation/network_traffic_annotation.h" @@ -15,12 +15,12 @@ // This class is an implementation of mojom::URLLoaderFactory that // creates a mojom::URLLoader. -class NetworkServiceURLLoaderFactory : public mojom::URLLoaderFactory { +class URLLoaderFactory : public mojom::URLLoaderFactory { public: // NOTE: |context| must outlive this instance. - NetworkServiceURLLoaderFactory(NetworkContext* context, uint32_t process_id); + URLLoaderFactory(NetworkContext* context, uint32_t process_id); - ~NetworkServiceURLLoaderFactory() override; + ~URLLoaderFactory() override; // mojom::URLLoaderFactory implementation. void CreateLoaderAndStart(mojom::URLLoaderRequest request, @@ -38,9 +38,9 @@ NetworkContext* context_; uint32_t process_id_; - DISALLOW_COPY_AND_ASSIGN(NetworkServiceURLLoaderFactory); + DISALLOW_COPY_AND_ASSIGN(URLLoaderFactory); }; } // namespace network -#endif // SERVICES_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_H_ +#endif // SERVICES_NETWORK_URL_LOADER_FACTORY_H_
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc index 98764e8e..fbd781df 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
@@ -129,18 +129,19 @@ bool want_mmaps, const std::vector<base::ProcessId>& pids, const RequestOSMemoryDumpCallback& callback) { + bool global_success = true; std::unordered_map<base::ProcessId, mojom::RawOSMemDumpPtr> results; for (const base::ProcessId& pid : pids) { mojom::RawOSMemDumpPtr result = mojom::RawOSMemDump::New(); result->platform_private_footprint = mojom::PlatformPrivateFootprint::New(); - bool success = true; - success = success && OSMetrics::FillOSMemoryDump(pid, result.get()); + bool success = OSMetrics::FillOSMemoryDump(pid, result.get()); if (want_mmaps) success = success && OSMetrics::FillProcessMemoryMaps(pid, result.get()); if (success) results[pid] = std::move(result); + global_success = global_success && success; } - callback.Run(true, std::move(results)); + callback.Run(global_success, std::move(results)); } ClientProcessImpl::Config::Config(service_manager::Connector* connector,
diff --git a/services/viz/privileged/interfaces/compositing/display_private.mojom b/services/viz/privileged/interfaces/compositing/display_private.mojom index 90a4e0e..f2082e6 100644 --- a/services/viz/privileged/interfaces/compositing/display_private.mojom +++ b/services/viz/privileged/interfaces/compositing/display_private.mojom
@@ -23,10 +23,16 @@ gfx.mojom.ColorSpace device_color_space); SetOutputIsSecure(bool secure); - // Locks the BeginFrame vsync interval for this display to |interval| and - // ignores vsync interval information from other sources. This will do nothing - // if the display is using an external BeginFrame source. + // Locks the vsync interval used to generate BeginFrames for this display to + // |interval|. Changes to vsync interval from other sources will be ignored. + // This will do nothing if the display is using an external BeginFrame source. SetAuthoritativeVSyncInterval(mojo.common.mojom.TimeDelta interval); + + // Updates vsync parameters used to generate BeginFrames for this display. + // This will do nothing if the display is using an external BeginFrame source. + SetDisplayVSyncParameters( + mojo.common.mojom.TimeTicks timebase, + mojo.common.mojom.TimeDelta interval); }; interface DisplayClient {
diff --git a/sql/BUILD.gn b/sql/BUILD.gn index e5278d0a..d2d3adef 100644 --- a/sql/BUILD.gn +++ b/sql/BUILD.gn
@@ -13,6 +13,8 @@ "error_delegate_util.cc", "error_delegate_util.h", "init_status.h", + "initialization.cc", + "initialization.h", "meta_table.cc", "meta_table.h", "recovery.cc",
diff --git a/sql/connection.cc b/sql/connection.cc index 76f9371..4fd3d41 100644 --- a/sql/connection.cc +++ b/sql/connection.cc
@@ -11,29 +11,28 @@ #include <utility> -#include "base/bind.h" #include "base/debug/alias.h" #include "base/debug/dump_without_crashing.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/format_macros.h" #include "base/json/json_file_value_serializer.h" -#include "base/lazy_instance.h" #include "base/location.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" +#include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" -#include "base/threading/sequenced_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "build/build_config.h" #include "sql/connection_memory_dump_provider.h" +#include "sql/initialization.h" #include "sql/meta_table.h" #include "sql/statement.h" #include "sql/vfs_wrapper.h" @@ -130,62 +129,6 @@ return true; } -void RecordSqliteMemory10Min() { - const int64_t used = sqlite3_memory_used(); - UMA_HISTOGRAM_COUNTS("Sqlite.MemoryKB.TenMinutes", used / 1024); -} - -void RecordSqliteMemoryHour() { - const int64_t used = sqlite3_memory_used(); - UMA_HISTOGRAM_COUNTS("Sqlite.MemoryKB.OneHour", used / 1024); -} - -void RecordSqliteMemoryDay() { - const int64_t used = sqlite3_memory_used(); - UMA_HISTOGRAM_COUNTS("Sqlite.MemoryKB.OneDay", used / 1024); -} - -void RecordSqliteMemoryWeek() { - const int64_t used = sqlite3_memory_used(); - UMA_HISTOGRAM_COUNTS("Sqlite.MemoryKB.OneWeek", used / 1024); -} - -// SQLite automatically calls sqlite3_initialize() lazily, but -// sqlite3_initialize() uses double-checked locking and thus can have -// data races. -// -// TODO(shess): Another alternative would be to have -// sqlite3_initialize() called as part of process bring-up. If this -// is changed, remove the dynamic_annotations dependency in sql.gyp. -base::LazyInstance<base::Lock>::Leaky - g_sqlite_init_lock = LAZY_INSTANCE_INITIALIZER; -void InitializeSqlite() { - base::AutoLock lock(g_sqlite_init_lock.Get()); - static bool first_call = true; - if (first_call) { - sqlite3_initialize(); - - // Schedule callback to record memory footprint histograms at 10m, 1h, and - // 1d. There may not be a registered task runner in tests. - if (base::SequencedTaskRunnerHandle::IsSet()) { - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&RecordSqliteMemory10Min), - base::TimeDelta::FromMinutes(10)); - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&RecordSqliteMemoryHour), - base::TimeDelta::FromHours(1)); - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&RecordSqliteMemoryDay), - base::TimeDelta::FromDays(1)); - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&RecordSqliteMemoryWeek), - base::TimeDelta::FromDays(7)); - } - - first_call = false; - } -} - // Helper to get the sqlite3_file* associated with the "main" database. int GetSqlite3File(sqlite3* db, sqlite3_file** file) { *file = NULL; @@ -642,7 +585,8 @@ // is _probably_ something systemic wrong with the user's system. So the lock // should never be contended, but when it is the database experience is // already bad. - base::AutoLock lock(g_sqlite_init_lock.Get()); + static base::NoDestructor<base::Lock> lock; + base::AutoLock auto_lock(*lock); std::unique_ptr<base::Value> root; if (!base::PathExists(breadcrumb_path)) { @@ -951,7 +895,8 @@ if (amount < 0) amount = 0; if (amount > 0) { - base::AutoLock lock(g_sqlite_init_lock.Get()); + static base::NoDestructor<base::Lock> lock; + base::AutoLock auto_lock(*lock); static sqlite3_int64 g_reads_allowed = 20 * 1024 * 1024; if (g_reads_allowed < amount) amount = g_reads_allowed; @@ -1220,8 +1165,7 @@ std::string wal_str = AsUTF8ForSQL(wal_path); std::string path_str = AsUTF8ForSQL(path); - // Make sure sqlite3_initialize() is called before anything else. - InitializeSqlite(); + EnsureSqliteInitialized(); sqlite3_vfs* vfs = sqlite3_vfs_find(NULL); CHECK(vfs); @@ -1645,8 +1589,7 @@ return false; } - // Make sure sqlite3_initialize() is called before anything else. - InitializeSqlite(); + EnsureSqliteInitialized(); // Setup the stats histograms immediately rather than allocating lazily. // Connections which won't exercise all of these probably shouldn't exist.
diff --git a/sql/initialization.cc b/sql/initialization.cc new file mode 100644 index 0000000..5aaff153 --- /dev/null +++ b/sql/initialization.cc
@@ -0,0 +1,70 @@ +// Copyright 2018 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 "sql/initialization.h" + +#include "base/bind.h" +#include "base/metrics/histogram_macros.h" +#include "base/no_destructor.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "third_party/sqlite/sqlite3.h" + +namespace sql { + +namespace { + +void RecordSqliteMemory10Min() { + const int64_t used = sqlite3_memory_used(); + UMA_HISTOGRAM_COUNTS("Sqlite.MemoryKB.TenMinutes", used / 1024); +} + +void RecordSqliteMemoryHour() { + const int64_t used = sqlite3_memory_used(); + UMA_HISTOGRAM_COUNTS("Sqlite.MemoryKB.OneHour", used / 1024); +} + +void RecordSqliteMemoryDay() { + const int64_t used = sqlite3_memory_used(); + UMA_HISTOGRAM_COUNTS("Sqlite.MemoryKB.OneDay", used / 1024); +} + +void RecordSqliteMemoryWeek() { + const int64_t used = sqlite3_memory_used(); + UMA_HISTOGRAM_COUNTS("Sqlite.MemoryKB.OneWeek", used / 1024); +} + +} // anonymous namespace + +void EnsureSqliteInitialized() { + // sqlite3_initialize() uses double-checked locking and thus can have + // data races. + static base::NoDestructor<base::Lock> sqlite_init_lock; + base::AutoLock auto_lock(*sqlite_init_lock); + + static bool first_call = true; + if (first_call) { + sqlite3_initialize(); + + // Schedule callback to record memory footprint histograms at 10m, 1h, and + // 1d. There may not be a registered task runner in tests. + if (base::SequencedTaskRunnerHandle::IsSet()) { + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordSqliteMemory10Min), + base::TimeDelta::FromMinutes(10)); + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordSqliteMemoryHour), + base::TimeDelta::FromHours(1)); + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordSqliteMemoryDay), + base::TimeDelta::FromDays(1)); + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::BindOnce(&RecordSqliteMemoryWeek), + base::TimeDelta::FromDays(7)); + } + + first_call = false; + } +} + +} // namespace sql
diff --git a/sql/initialization.h b/sql/initialization.h new file mode 100644 index 0000000..6f134585 --- /dev/null +++ b/sql/initialization.h
@@ -0,0 +1,23 @@ +// Copyright 2018 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 SQL_INITIALIZATION_H_ +#define SQL_INITIALIZATION_H_ + +#include "sql/sql_export.h" + +namespace sql { + +// Makes sure that sqlite3_initialize() is called. +// +// Users of the APIs exposed in //sql do not need to worry about SQLite +// initialization, because sql::Connection calls this function internally. +// +// The function is exposed for other components that use SQLite indirectly, such +// as Blink. +SQL_EXPORT void EnsureSqliteInitialized(); + +} // namespace sql + +#endif // SQL_INITIALIZATION_H_
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index bf31a7d..6920afa8 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -2201,6 +2201,9 @@ "test": "junit_unit_tests" }, { + "test": "media_base_junit_tests" + }, + { "test": "net_junit_tests" }, { @@ -3883,6 +3886,9 @@ "test": "junit_unit_tests" }, { + "test": "media_base_junit_tests" + }, + { "test": "net_junit_tests" }, {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 5249a48..5dbbb43 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -10119,6 +10119,144 @@ ], "isolated_scripts": [] }, + "Optional Linux Release (Intel HD 630)": { + "gtest_tests": [ + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ] + }, + "test": "angle_end2end_tests", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gles2_conform_test", + "use_xvfb": false + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ] + }, + "test": "swiftshader_unittests", + "use_xvfb": false + } + ], + "isolated_scripts": [ + { + "args": [ + "info_collection", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--expected-vendor-id", + "8086", + "--expected-device-id", + "5912" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "info_collection_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl2_conformance_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ], + "shards": 20 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_gl_passthrough_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Ubuntu", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + } + ] + }, "Optional Linux Release (NVIDIA)": { "gtest_tests": [ { @@ -10685,6 +10823,292 @@ } ] }, + "Optional Win10 Release (Intel HD 630)": { + "gtest_tests": [ + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + }, + "test": "angle_end2end_tests", + "use_xvfb": false + }, + { + "args": [ + "--test-launcher-retry-limit=0" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + }, + "test": "angle_white_box_tests", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests", + "--use-angle=d3d9" + ], + "name": "gles2_conform_d3d9_test", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gles2_conform_test", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests", + "--use-angle=gl", + "--disable-gpu-sandbox" + ], + "name": "gles2_conform_gl_test", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gles2_conform_test", + "use_xvfb": false + }, + { + "args": [ + "--use-gpu-in-tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gles2_conform_test", + "use_xvfb": false + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + }, + "test": "gpu_unittests", + "use_xvfb": false + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + }, + "test": "swiftshader_unittests", + "use_xvfb": false + } + ], + "isolated_scripts": [ + { + "args": [ + "info_collection", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--expected-vendor-id", + "8086", + "--expected-device-id", + "5912" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "info_collection_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl2_conformance_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "shards": 20 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=passthrough" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_d3d11_passthrough_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=passthrough" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_d3d9_passthrough_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=validating" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_d3d9_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" + ], + "isolate_name": "telemetry_gpu_integration_test", + "name": "webgl_conformance_gl_passthrough_tests", + "override_compile_targets": [ + "telemetry_gpu_integration_test" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "shards": 2 + } + } + ] + }, "Optional Win10 Release (NVIDIA)": { "gtest_tests": [ {
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index a8ee853..613fc8d 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -1,6 +1,4 @@ { - "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, - "AAAAA2 See //tools/perf/generate_perf_data to make changes": {}, "Android Nexus 5X Perf FYI": { "isolated_scripts": [ {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index d01a287f..88fb1d7 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -32020,6 +32020,27 @@ } }, { + "args": [], + "isolate_name": "views_perftests", + "name": "views_perftests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3", + "id": "build31-a9", + "os": "Ubuntu-14.04", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 1200, + "upload_test_results": true + } + }, + { "args": [ "wasm", "-v", @@ -36041,6 +36062,27 @@ } }, { + "args": [], + "isolate_name": "views_perftests", + "name": "views_perftests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "id": "build160-m1", + "os": "Mac-10.12", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 1200, + "upload_test_results": true + } + }, + { "args": [ "wasm", "-v", @@ -51861,6 +51903,27 @@ } }, { + "args": [], + "isolate_name": "views_perftests", + "name": "views_perftests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0534", + "id": "build135-m1", + "os": "Windows-10-10240", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 1200, + "upload_test_results": true + } + }, + { "args": [ "wasm", "-v",
diff --git a/testing/buildbot/filters/fuchsia.base_unittests.filter b/testing/buildbot/filters/fuchsia.base_unittests.filter index c8586b8..70706df 100644 --- a/testing/buildbot/filters/fuchsia.base_unittests.filter +++ b/testing/buildbot/filters/fuchsia.base_unittests.filter
@@ -77,3 +77,6 @@ # Flaky, https://crbug.com/810077. -MessageLoopTypedTest.RecursivePosts/* + +# Flaky, https://crbug.com/735701. +-TaskSchedulerWorkerPoolHistogramTest.NumTasksBeforeCleanup
diff --git a/testing/buildbot/filters/fuchsia.net_unittests.filter b/testing/buildbot/filters/fuchsia.net_unittests.filter index b64767a6..0edc433 100644 --- a/testing/buildbot/filters/fuchsia.net_unittests.filter +++ b/testing/buildbot/filters/fuchsia.net_unittests.filter
@@ -20,3 +20,6 @@ # Flaky, https://crbug.com/793176. -NetworkQualityEstimatorTest.RecordAccuracy + +# Flaky, https://crbug.com/810521. +-DiskCacheEntryTest.ExternalAsyncIONoBuffer
diff --git a/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter b/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter index 928fc179..abc61366 100644 --- a/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter
@@ -262,7 +262,3 @@ -EnterpriseEnrollmentTest.TestAuthCodeGetsProperlyReceivedFromGaia -PowerPolicyLoginScreenBrowserTest.SetDevicePolicy -EnterpriseEnrollmentTest.TestActiveDirectoryEnrollment_Success - -# Crashes in cc::(anonymous namespace)::ZeroCopyGpuBacking::SharedMemoryGuid -# http://crbug.com/810073 --MemoryTracingBrowserTest.TestHeapProfilingPseudo
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index a8357c7..bc77e4d7 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -724,6 +724,10 @@ "label": "//mash:all", "type": "additional_compile_target", }, + "media_base_junit_tests": { + "label": "//media/base/android:media_base_junit_tests", + "type": "junit_test", + }, "media_unittests": { "label": "//media:media_unittests", "type": "windowed_test_launcher",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index d8c3f600..096f029 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -467,6 +467,7 @@ 'content_junit_tests': {}, 'device_junit_tests': {}, 'junit_unit_tests': {}, + 'media_base_junit_tests': {}, 'net_junit_tests': {}, 'service_junit_tests': {}, 'ui_junit_tests': {},
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index de01850b..10cd5973 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -129,6 +129,7 @@ crbug.com/591099 animations/stability/element-animate-float-crash.html [ Failure ] crbug.com/591099 animations/timing/timing-model.html [ Timeout ] crbug.com/591099 bindings/blink-in-js-asan-crash.html [ Failure ] +crbug.com/591099 bindings/webidl-type-mapping.html [ Timeout ] crbug.com/714962 compositing/background-color/view-blending-base-background.html [ Failure ] crbug.com/591099 compositing/child-transform-layer-requires-box.html [ Failure ] crbug.com/591099 compositing/compositing-visible-descendant.html [ Failure ] @@ -152,46 +153,8 @@ crbug.com/591099 compositing/geometry/transformed-abs-position-inside-composited.html [ Failure ] crbug.com/591099 compositing/geometry/transfrom-origin-on-zero-size-layer.html [ Failure ] crbug.com/591099 compositing/geometry/video-opacity-overlay.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-late-composite.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-late-noncomposite.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-composited.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-scrolled.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-composited-scroll-clip.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-composited-scrolled.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-composited.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-layout-change-2.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-layout-change.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled-late-composite.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled-late-noncomposite.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-iframe-composited-inner.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-iframe-composited-outer.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-inner-late-composite.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-inner.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-outer-late-composite.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-outer.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-iframe.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner-scroll-inner.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner-scroll-outer.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer-scroll-inner.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer-scroll-outer.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer.html [ Failure ] crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-scrolled-inner.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-scrolled-outer.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-img-and-text.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-on-promoted-overflow-div-scrolled.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-pixel-rotated-link.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-pixel-transparent.html [ Failure ] crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-multi-line.html [ Pass ] -crbug.com/591099 compositing/gestures/gesture-tapHighlight-simple-scaledX.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-scaledY.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-window-scroll.html [ Failure ] -crbug.com/714962 compositing/gestures/gesture-tapHighlight-with-box-shadow.html [ Failure ] crbug.com/714962 compositing/gestures/gesture-tapHighlight-with-squashing.html [ Pass ] crbug.com/591099 compositing/iframes/composited-iframe-alignment.html [ Failure ] crbug.com/591099 compositing/iframes/floating-self-painting-frame.html [ Failure ] @@ -2802,7 +2765,7 @@ crbug.com/591099 fast/css/text-overflow-ellipsis-text-align-justify.html [ Failure ] crbug.com/591099 fast/css/text-overflow-ellipsis-text-align-left.html [ Failure ] crbug.com/591099 fast/css/text-overflow-ellipsis-text-align-right.html [ Failure ] -crbug.com/714962 fast/css/text-overflow-ellipsis-vertical-hittest.html [ Timeout ] +crbug.com/714962 fast/css/text-overflow-ellipsis-vertical-hittest.html [ Failure ] crbug.com/591099 fast/css/text-overflow-ellipsis-vertical-select.html [ Failure ] crbug.com/591099 fast/css/text-overflow-ellipsis.html [ Failure ] crbug.com/591099 fast/css/text-overflow-input.html [ Failure ] @@ -3677,7 +3640,6 @@ crbug.com/591099 fast/js/missing-title-end-tag-js.html [ Failure ] crbug.com/591099 fast/js/same-origin-subframe-about-blank.html [ Failure ] crbug.com/591099 fast/js/toString-and-valueOf-override.html [ Failure ] -crbug.com/591099 fast/js/webidl-type-mapping.html [ Timeout ] crbug.com/591099 fast/layers/add-layer-with-nested-stacking.html [ Failure ] crbug.com/591099 fast/layers/layer-content-visibility-change.html [ Failure ] crbug.com/591099 fast/layers/layer-visibility-sublayer.html [ Failure ] @@ -4247,9 +4209,9 @@ crbug.com/591099 fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html [ Failure ] crbug.com/591099 fast/replaced/image-map-2.html [ Failure ] crbug.com/591099 fast/replaced/max-width-percent.html [ Failure ] -crbug.com/591099 fast/replaced/no-focus-ring-embed.html [ Timeout ] -crbug.com/591099 fast/replaced/no-focus-ring-iframe.html [ Timeout ] -crbug.com/591099 fast/replaced/no-focus-ring-object.html [ Timeout ] +crbug.com/591099 fast/replaced/no-focus-ring-embed.html [ Failure ] +crbug.com/591099 fast/replaced/no-focus-ring-iframe.html [ Failure ] +crbug.com/591099 fast/replaced/no-focus-ring-object.html [ Failure ] crbug.com/591099 fast/replaced/object-with-non-empty-classid-triggers-fallback.html [ Failure ] crbug.com/591099 fast/replaced/percent-height-in-anonymous-block-in-table.html [ Failure ] crbug.com/591099 fast/replaced/percent-height-in-anonymous-block.html [ Failure ] @@ -4646,7 +4608,6 @@ crbug.com/591099 fast/text-autosizing/wide-in-narrow-overflow-scroll.html [ Failure ] crbug.com/714962 fast/text/atsui-multiple-renderers.html [ Failure ] crbug.com/591099 fast/text/break-word-with-floats.html [ Failure ] -crbug.com/591099 fast/text/capitalize-boundaries.html [ Failure ] crbug.com/591099 fast/text/chromium-linux-fontconfig-renderstyle.html [ Failure ] crbug.com/591099 fast/text/complex-text-opacity.html [ Failure ] crbug.com/591099 fast/text/container-align-with-inlines.html [ Failure ] @@ -4657,8 +4618,6 @@ crbug.com/714962 fast/text/ellipsis-in-justified-text.html [ Failure ] crbug.com/591099 fast/text/ellipsis-in-relative-inline-right.html [ Failure ] crbug.com/591099 fast/text/ellipsis-in-relative-inline.html [ Failure ] -crbug.com/591099 fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2.html [ Failure ] -crbug.com/591099 fast/text/ellipsis-mixed-text-in-rtl-flow-underline.html [ Failure ] crbug.com/591099 fast/text/ellipsis-platform-font-change.html [ Failure ] crbug.com/591099 fast/text/ellipsis-with-list-marker-in-ltr-flow.html [ Failure ] crbug.com/591099 fast/text/ellipsis-with-list-marker-in-rtl-flow.html [ Failure ] @@ -4730,8 +4689,6 @@ crbug.com/591099 fast/text/selection/selection-with-inline-padding.html [ Failure ] crbug.com/714962 fast/text/selection/shaping-selection-rect.html [ Failure ] crbug.com/714962 fast/text/selection/thai-offsetForPosition-inside-character.html [ Failure ] -crbug.com/714962 fast/text/stroking-decorations.html [ Failure ] -crbug.com/591099 fast/text/sub-pixel/text-scaling-pixel.html [ Failure ] crbug.com/714962 fast/text/text-range-bounds.html [ Failure ] crbug.com/714962 fast/text/transform-text-first-line-capitalize.html [ Failure ] crbug.com/714962 fast/text/transform-text-first-line-lowercase.html [ Failure ] @@ -5189,13 +5146,13 @@ crbug.com/591099 http/tests/navigation/form-targets-cross-site-frame-post.html [ Failure ] crbug.com/591099 http/tests/navigation/form-with-enctype-targets-cross-site-frame.html [ Failure ] crbug.com/591099 http/tests/navigation/history-back-across-form-submission-to-fragment.html [ Failure ] -crbug.com/591099 http/tests/navigation/javascriptlink-basic.html [ Timeout ] +crbug.com/591099 http/tests/navigation/javascriptlink-basic.html [ Failure ] crbug.com/714962 http/tests/navigation/javascriptlink-frames.html [ Timeout ] -crbug.com/591099 http/tests/navigation/javascriptlink-goback.html [ Timeout ] +crbug.com/591099 http/tests/navigation/javascriptlink-goback.html [ Failure ] crbug.com/714962 http/tests/navigation/javascriptlink-subframeload.html [ Timeout ] crbug.com/591099 http/tests/navigation/metaredirect-basic.html [ Failure ] crbug.com/591099 http/tests/navigation/metaredirect-goback.html [ Failure ] -crbug.com/591099 http/tests/navigation/no-referrer-reset.html [ Timeout ] +crbug.com/591099 http/tests/navigation/no-referrer-reset.html [ Failure ] crbug.com/591099 http/tests/navigation/no-referrer-same-window.html [ Timeout ] crbug.com/714962 http/tests/navigation/no-referrer-subframe.html [ Timeout ] crbug.com/591099 http/tests/navigation/no-referrer-target-blank.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 80b129f8..3d2b262 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2302,10 +2302,6 @@ crbug.com/707359 [ Mac ] fast/css-grid-layout/grid-self-baseline-vertical-rl-04.html [ Failure ] crbug.com/707359 [ Mac ] fast/css-grid-layout/grid-self-baseline-vertical-rl-05.html [ Failure ] -# [css-align] -crbug.com/726148 external/wpt/css/css-align/default-alignment/parse-justify-items-002.html [ Failure ] -crbug.com/726147 external/wpt/css/css-align/default-alignment/parse-justify-items-004.html [ Failure ] - # [selectors-4] crbug.com/706118 external/wpt/css/selectors/focus-within-004.html [ Failure ] crbug.com/576815 external/wpt/css/selectors/selectors-dir-selector-ltr-001.html [ Failure ] @@ -2491,6 +2487,9 @@ crbug.com/678346 [ Debug ] fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ] crbug.com/678346 [ Win7 Mac Debug ] storage/indexeddb/index-cursor.html [ Pass Timeout ] +crbug.com/810254 [ Win7 ] storage/indexeddb/observer-frame.html [ Pass Timeout ] +crbug.com/810254 [ Win7 ] storage/indexeddb/observer-workers.html [ Pass Timeout ] + crbug.com/678346 [ Win7 Debug ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ] # Temporarily disabled due to conflicting NeedsManualRebaseline below # crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ] @@ -3233,13 +3232,13 @@ # Sheriff failures 2018-01-23 # Flaking on linux_chromium_rel_ng crbug.com/804709 [ Linux ] virtual/gpu/fast/canvas/canvas-fillPath-shadow.html [ Pass Failure ] -crbug.com/805788 [ Linux Win7 Win10 ] virtual/threaded/animations/responsive/viewport-unit-transform-responsive.html [ Pass Timeout ] +crbug.com/805788 [ Linux Win7 Win10 Mac ] virtual/threaded/animations/responsive/viewport-unit-transform-responsive.html [ Pass Timeout ] # Sheriff failures 2018-01-25 # Flaking on Linux Tests, WebKit Linux Trusty (also ASAN, Leak) crbug.com/805794 [ Linux ] virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-shown.html [ Pass Failure ] crbug.com/805794 [ Linux ] virtual/android/url-bar/bottom-fixed-adjusted-when-showing-url-bar.html [ Pass Failure ] -crbug.com/805794 [ Linux Win ] virtual/threaded/animations/responsive/viewport-unit-translate-responsive.html [ Pass Timeout ] +crbug.com/805794 [ Linux Win Mac ] virtual/threaded/animations/responsive/viewport-unit-translate-responsive.html [ Pass Timeout ] # Sheriff failures 2018-02-05 crbug.com/809152 netinfo/estimate-multiple-frames.html [ Pass Failure ] @@ -3284,17 +3283,6 @@ crbug.com/417782 inspector-protocol/css/css-get-background-colors.js [ Failure ] crbug.com/417782 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot.js [ Failure ] crbug.com/417782 inspector-protocol/page/get-layout-metrics.js [ Failure ] -crbug.com/417782 paint/invalidation/background/body-background-image.html [ Failure ] -crbug.com/417782 paint/invalidation/background/viewport-gradient-background-html-move-overflow.html [ Failure ] -crbug.com/417782 paint/invalidation/background/viewport-gradient-background-html-resize-overflow.html [ Failure ] -crbug.com/417782 paint/invalidation/compositing/iframe-inside-squashed-layer.html [ Failure ] -crbug.com/417782 paint/invalidation/filters/filter-on-html-element-with-fixed-position-child.html [ Failure ] -crbug.com/417782 paint/invalidation/reflection/reflection-with-rotation.html [ Failure ] -crbug.com/417782 paint/invalidation/scroll/overflow-scroll-body-appear.html [ Failure ] -crbug.com/417782 paint/invalidation/scroll/repaint-during-scroll-with-zoom.html [ Failure ] -crbug.com/417782 paint/invalidation/scroll/scrolled-iframe-scrollbar-change.html [ Failure ] -crbug.com/417782 paint/invalidation/svg/absolute-sized-document-no-scrollbars.svg [ Failure ] -crbug.com/417782 paint/invalidation/svg/relative-sized-document-scrollbars.svg [ Failure ] crbug.com/417782 paint/invalidation/window-resize/window-resize-vertical-writing-mode.html [ Crash ] crbug.com/417782 [ Linux ] paint/overflow/fixed-background-scroll-window.html [ Failure ] crbug.com/417782 transforms/selection-bounds-in-transformed-view.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/accessibility/aom-computed-accessible-node.html b/third_party/WebKit/LayoutTests/accessibility/aom-computed-accessible-node.html index 7da225d..ea3f726 100644 --- a/third_party/WebKit/LayoutTests/accessibility/aom-computed-accessible-node.html +++ b/third_party/WebKit/LayoutTests/accessibility/aom-computed-accessible-node.html
@@ -21,27 +21,25 @@ async_test(async function(test) { var element = document.getElementById("button1"); - var computedAXNode = await window.getComputedAccessibleNode(element) + var computedAXNode = await window.getComputedAccessibleNode(element); assert_true(computedAXNode != null); test.done(); }, 'Ensure that a non null value is returned from getComputedAccessibleNode'); - async_test(async function(test) { var element = document.getElementById("button1"); var computedAXNode1 = await window.getComputedAccessibleNode(element); var computedAXNode2 = await window.getComputedAccessibleNode(element); - assert_true(computedAXNode1 === computedAXNode2); + // TODO(meredithl): Change this back to assert_true once possible. + assert_false(computedAXNode1 === computedAXNode2); test.done(); -}, "Multiple calls to getComputedAccessibleNode will return the same node."); - +}, "Multiple calls to getComputedAccessibleNode will not return the same node."); </script> <div id="button2" role="button" aria-label="axButton">Click</div> <script> - async_test(async function(test) { var button1 = document.getElementById("button1"); var button1CAXNode = await window.getComputedAccessibleNode(button1); @@ -62,9 +60,8 @@ // nullified. assert_equals(button1CAXNode.name, null); assert_equals(button1CAXNode.role, null); - test.done(); + test.done(); }, "Deleting nodes from the accessibility tree will not cause a crash, and properties on any references to a deleted computed accessible node have been nullified."); </script> -
diff --git a/third_party/WebKit/LayoutTests/accessibility/aom-computed-relation-accessors.html b/third_party/WebKit/LayoutTests/accessibility/aom-computed-relation-accessors.html index 21c9c0e0..de8d3c0 100644 --- a/third_party/WebKit/LayoutTests/accessibility/aom-computed-relation-accessors.html +++ b/third_party/WebKit/LayoutTests/accessibility/aom-computed-relation-accessors.html
@@ -29,56 +29,69 @@ var computedParent = computedAXNode.parent; assert_false(computedParent === null); assert_equals(computedParent.name, "container"); - assert_true(computedParent.firstChild === computedAXNode); - // Parent of listbox should be null. - assert_equals(computedParent.parent, null); + // TODO(meredithl): assert_true(computedParent.firstChild === computedAXNode); + + // Non-Element nodes may be explored to via the tree + assert_equals(computedParent.parent.role, "rootWebArea"); test.done(); }, "ComputedAccessibleNode.parent."); async_test(async function(test) { var element = document.getElementById("listbox"); var computedAXNode = await window.getComputedAccessibleNode(element); + var computedChild = computedAXNode.firstChild assert_false(computedChild === null); assert_equals(computedChild.name, "Option 1"); - assert_true(computedChild.parent === computedAXNode); + + // TODO(meredithl): assert_true(computedChild.parent === computedAXNode); + test.done(); }, "ComputedAccessibleNode.firstChild."); async_test(async function(test) { var element = document.getElementById("listbox"); var computedAXNode = await window.getComputedAccessibleNode(element); + var computedChild = computedAXNode.lastChild; assert_false(computedChild === null); assert_equals(computedChild.name, "Option 3"); - assert_true(computedChild.parent === computedAXNode); + + // TODO(meredithl): assert_true(computedChild.parent === computedAXNode); + test.done(); }, "ComputedAccessibleNode.lastChild."); async_test(async function(test) { var element = document.getElementById("option2"); var computedAXNode = await window.getComputedAccessibleNode(element); + var computedSibling = computedAXNode.previousSibling; assert_false(computedSibling === null); assert_equals(computedSibling.name, "Option 1"); // Check that a call to non-existant sibling is null. assert_equals(computedSibling.previousSibling, null); - assert_true(computedSibling.nextSibling === computedAXNode); + + // TODO(meredithl): assert_true(computedSibling.nextSibling === computedAXNode); + test.done(); }, "ComputedAccessibleNode.previousSibling"); async_test(async function(test) { var element = document.getElementById("option2"); var computedAXNode = await window.getComputedAccessibleNode(element); + var computedSibling = computedAXNode.nextSibling; assert_false(computedSibling === null); assert_equals(computedSibling.name, "Option 3"); // Check that a call to non-existant sibling is null. assert_equals(computedSibling.nextSibling, null); - assert_true(computedSibling.previousSibling === computedAXNode); + + // TODO(meredithl): assert_true(computedSibling.previousSibling === computedAXNode); + test.done(); }, "ComputedAccessibleNode.nextSibling");
diff --git a/third_party/WebKit/LayoutTests/accessibility/table-with-th-role-gridcell-crash.html b/third_party/WebKit/LayoutTests/accessibility/table-with-th-role-gridcell-crash.html new file mode 100644 index 0000000..b2295324 --- /dev/null +++ b/third_party/WebKit/LayoutTests/accessibility/table-with-th-role-gridcell-crash.html
@@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<style> +tr { + display: grid; + } +</style> +<table role="grid"> + <th id="cell1" role="gridcell"></th> +</table> + +<script> +function axElementById(id) { + return accessibilityController.accessibleElementById(id); +} + +test(function(t) { + var ax = axElementById("cell1"); + assert_equals(ax.role, "AXRole: AXCell"); +}, "A <th role='gridcell'> in a table with extra layout objects doesn't crash"); +</script> +<!-- + +<script> +function axElementById(id) { + return accessibilityController.accessibleElementById(id); +} +</script> +-->
diff --git a/third_party/WebKit/LayoutTests/fast/js/webidl-attribute-getter-setter-lengths-expected.txt b/third_party/WebKit/LayoutTests/bindings/webidl-attribute-getter-setter-lengths-expected.txt similarity index 100% rename from third_party/WebKit/LayoutTests/fast/js/webidl-attribute-getter-setter-lengths-expected.txt rename to third_party/WebKit/LayoutTests/bindings/webidl-attribute-getter-setter-lengths-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/js/webidl-attribute-getter-setter-lengths.html b/third_party/WebKit/LayoutTests/bindings/webidl-attribute-getter-setter-lengths.html similarity index 93% rename from third_party/WebKit/LayoutTests/fast/js/webidl-attribute-getter-setter-lengths.html rename to third_party/WebKit/LayoutTests/bindings/webidl-attribute-getter-setter-lengths.html index 2e81d280f..20c36bb 100644 --- a/third_party/WebKit/LayoutTests/fast/js/webidl-attribute-getter-setter-lengths.html +++ b/third_party/WebKit/LayoutTests/bindings/webidl-attribute-getter-setter-lengths.html
@@ -1,6 +1,6 @@ <!DOCTYPE html> <meta charset="utf-8"> -<script src="../../resources/js-test.js"></script> +<script src="../resources/js-test.js"></script> <script> description("Verify WebIDL interface attribute getter/setter function lengths");
diff --git a/third_party/WebKit/LayoutTests/fast/js/webidl-operation-functions-should-have-no-prototype-expected.txt b/third_party/WebKit/LayoutTests/bindings/webidl-operation-functions-should-have-no-prototype-expected.txt similarity index 100% rename from third_party/WebKit/LayoutTests/fast/js/webidl-operation-functions-should-have-no-prototype-expected.txt rename to third_party/WebKit/LayoutTests/bindings/webidl-operation-functions-should-have-no-prototype-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/js/webidl-operation-functions-should-have-no-prototype.html b/third_party/WebKit/LayoutTests/bindings/webidl-operation-functions-should-have-no-prototype.html similarity index 77% rename from third_party/WebKit/LayoutTests/fast/js/webidl-operation-functions-should-have-no-prototype.html rename to third_party/WebKit/LayoutTests/bindings/webidl-operation-functions-should-have-no-prototype.html index 2e7d4e883..73fe883 100644 --- a/third_party/WebKit/LayoutTests/fast/js/webidl-operation-functions-should-have-no-prototype.html +++ b/third_party/WebKit/LayoutTests/bindings/webidl-operation-functions-should-have-no-prototype.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<script src="../../resources/js-test.js"></script> +<script src="../resources/js-test.js"></script> <script> description("WebIDL operation functions should not have a prototype property.");
diff --git a/third_party/WebKit/LayoutTests/fast/js/webidl-sequence-conversion.html b/third_party/WebKit/LayoutTests/bindings/webidl-sequence-conversion.html similarity index 88% rename from third_party/WebKit/LayoutTests/fast/js/webidl-sequence-conversion.html rename to third_party/WebKit/LayoutTests/bindings/webidl-sequence-conversion.html index 7d69910c..1264659 100644 --- a/third_party/WebKit/LayoutTests/fast/js/webidl-sequence-conversion.html +++ b/third_party/WebKit/LayoutTests/bindings/webidl-sequence-conversion.html
@@ -1,6 +1,6 @@ <!DOCTYPE html> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> <body> <div></div> <script>
diff --git a/third_party/WebKit/LayoutTests/fast/js/webidl-type-mapping-expected.txt b/third_party/WebKit/LayoutTests/bindings/webidl-type-mapping-expected.txt similarity index 100% rename from third_party/WebKit/LayoutTests/fast/js/webidl-type-mapping-expected.txt rename to third_party/WebKit/LayoutTests/bindings/webidl-type-mapping-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/js/webidl-type-mapping.html b/third_party/WebKit/LayoutTests/bindings/webidl-type-mapping.html similarity index 99% rename from third_party/WebKit/LayoutTests/fast/js/webidl-type-mapping.html rename to third_party/WebKit/LayoutTests/bindings/webidl-type-mapping.html index 7887e4cf..b1132f8 100644 --- a/third_party/WebKit/LayoutTests/fast/js/webidl-type-mapping.html +++ b/third_party/WebKit/LayoutTests/bindings/webidl-type-mapping.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<script src="../../resources/js-test.js"></script> +<script src="../resources/js-test.js"></script> <script> description("Exercise WebIDL type conversions.");
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 68b63a6..4d8f8974 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -170723,6 +170723,12 @@ {} ] ], + "css/css-color/color-function-parsing.html": [ + [ + "/css/css-color/color-function-parsing.html", + {} + ] + ], "css/css-color/color-resolving-hsl.html": [ [ "/css/css-color/color-resolving-hsl.html", @@ -261652,6 +261658,10 @@ "ec85953fb0594db50a69ca9952092aeab403cf2c", "reftest" ], + "css/css-color/color-function-parsing.html": [ + "7c6abb0ab3f4c08d075cb1a5a13fe78964d55e15", + "testharness" + ], "css/css-color/color-resolving-hsl.html": [ "672137820a0289306d53b3866ffa1f00daacc019", "testharness"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-align/content-distribution/place-content-shorthand-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-align/content-distribution/place-content-shorthand-004.html index 30f45b6..3f9bd88 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-align/content-distribution/place-content-shorthand-004.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-align/content-distribution/place-content-shorthand-004.html
@@ -48,6 +48,12 @@ }, "Verify 'auto' values are invalid"); test(function() { + checkInvalidValues("self-start") + checkInvalidValues("center self-end") + checkInvalidValues("self-end start") + }, "Verify self-position values are invalid"); + + test(function() { checkInvalidValues("") }, "Verify empty declaration is invalid"); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-align/default-alignment/parse-justify-items-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-align/default-alignment/parse-justify-items-002.html index 6ba2c7c2..1806fa2 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-align/default-alignment/parse-justify-items-002.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-align/default-alignment/parse-justify-items-002.html
@@ -19,39 +19,39 @@ test(function() { element = document.createElement("div"); document.body.appendChild(element); - checkValues(element, "justifyItems", "justify-items", "", "legacy"); + checkValues(element, "justifyItems", "justify-items", "", "normal"); }, "Test 'initial' value when nothing is specified"); test(function() { container.style.display = ""; - checkInitialValues(element, "justifyItems", "justify-items", "center", "legacy"); + checkInitialValues(element, "justifyItems", "justify-items", "center", "normal"); }, "Test justify-items: 'initial'"); test(function() { container.style.display = "grid"; - checkInitialValues(element, "justifyItems", "justify-items", "safe start", "legacy"); + checkInitialValues(element, "justifyItems", "justify-items", "safe start", "normal"); }, "Test grid items justify-items: 'initial'"); test(function() { container.style.display = "flex"; - checkInitialValues(element, "justifyItems", "justify-items", "unsafe end", "legacy"); + checkInitialValues(element, "justifyItems", "justify-items", "unsafe end", "normal"); }, "Test flex items justify-items: 'initial'"); test(function() { container.style.display = ""; element.style.position = "absolute"; - checkInitialValues(element, "justifyItems", "justify-items", "start", "legacy"); + checkInitialValues(element, "justifyItems", "justify-items", "start", "normal"); }, "Test absolute positioned elements justify-items: 'initial'"); test(function() { container.style.display = "grid"; element.style.position = "absolute"; - checkInitialValues(element, "justifyItems", "justify-items", "end", "legacy"); + checkInitialValues(element, "justifyItems", "justify-items", "end", "normal"); }, "Test absolute positioned grid items justify-items: 'initial'"); test(function() { container.style.display = "flex"; element.style.position = "absolute"; - checkInitialValues(element, "justifyItems", "justify-items", "end", "legacy"); + checkInitialValues(element, "justifyItems", "justify-items", "end", "normal"); }, "Test absolute positioned flex items justify-items: 'initial'"); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-align/default-alignment/place-items-shorthand-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-align/default-alignment/place-items-shorthand-004.html index c5d9472..aa3ff30 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-align/default-alignment/place-items-shorthand-004.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-align/default-alignment/place-items-shorthand-004.html
@@ -37,7 +37,18 @@ checkInvalidValues("auto") checkInvalidValues("auto right") checkInvalidValues("auto auto") - }, "Verify 'auto' value is invalid as first longhand value."); + checkInvalidValues("center auto") + }, "Verify 'auto' value is invalid."); + + test(function() { + checkInvalidValues("legacy") + checkInvalidValues("legacy start") + checkInvalidValues("end legacy") + checkInvalidValues("legacy left") + checkInvalidValues("center legacy") + checkInvalidValues("start legacy center") + }, "Verify 'legacy' value is invalid."); + test(function() { checkInvalidValues("")
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-color/color-function-parsing.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/color-function-parsing.html new file mode 100644 index 0000000..7f483bb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/color-function-parsing.html
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Color 4: color() parsing</title> +<link rel="help" href="https://drafts.csswg.org/css-color-4/#color-function"> +<meta name="assert" content="Tests basic parsing of the color function"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="test"></div> +<script> + const div = document.querySelector("#test"); + function testColorFunction(description, rule, expectedValue) { + test(function() { + div.style.color = "black"; + div.style.color = rule; + assert_equals(getComputedStyle(div).color, expectedValue); + }, description); + } + + testColorFunction("Basic sRGB white", "color(srgb 1 1 1)", "color(srgb 1 1 1)"); + testColorFunction("White with lots of space", "color( srgb 1 1 1 )", "color(srgb 1 1 1)"); + testColorFunction("sRGB color", "color(srgb 0.25 0.5 0.75)", "color(srgb 0.25 0.5 0.75)"); + testColorFunction("Different case for sRGB", "color(SrGb 0.25 0.5 0.75)", "color(srgb 0.25 0.5 0.75)"); + testColorFunction("sRGB color with unnecessary decimals", "color(srgb 1.00000 0.500000 0.20)", "color(srgb 1 0.5 0.2)"); + testColorFunction("sRGB white with 0.5 alpha", "color(srgb 1 1 1 / 0.5)", "color(srgb 1 1 1 / 0.5)"); + testColorFunction("sRGB white with 0 alpha", "color(srgb 1 1 1 / 0)", "color(srgb 1 1 1 / 0)"); + testColorFunction("sRGB white with 50% alpha", "color(srgb 1 1 1 / 50%)", "color(srgb 1 1 1 / 0.5)"); + testColorFunction("sRGB white with 0% alpha", "color(srgb 1 1 1 / 0%)", "color(srgb 1 1 1 / 0)"); + testColorFunction("One missing component is 0", "color(srgb 1 1)", "color(srgb 1 1 0)"); + testColorFunction("Two missing components are 0", "color(srgb 1)", "color(srgb 1 0 0)"); + testColorFunction("All components missing", "color(srgb)", "color(srgb 0 0 0)"); + testColorFunction("Display P3 color", "color(display-p3 0.6 0.7 0.8)", "color(display-p3 0.6 0.7 0.8)"); + testColorFunction("Different case for Display P3", "color(dIspLaY-P3 0.6 0.7 0.8)", "color(display-p3 0.6 0.7 0.8)"); + + testColorFunction("Unknown color space should fallback", "color(unknown 1 2 3, red)", "color(unknown 1 2 3, red)"); + + testColorFunction("sRGB color with negative component should clamp to 0", "color(srgb -0.25 0.5 0.75)", "color(srgb 0 0.5 0.75)"); + testColorFunction("sRGB color with component > 1 should clamp", "color(srgb 0.25 1.5 0.75)", "color(srgb 0.25 1 0.75)"); + testColorFunction("Display P3 color with negative component should clamp to 0", "color(display-p3 0.5 -199 0.75)", "color(display-p3 0.5 0 0.75)"); + testColorFunction("Display P3 color with component > 1 should clamp", "color(display-p3 184 1.00001 2347329746587)", "color(display-p3 1 1 1)"); + testColorFunction("Alpha > 1 should clamp", "color(srgb 0.1 0.2 0.3 / 1.9)", "color(srgb 0.1 0.2 0.3)"); + testColorFunction("Negative alpha should clamp", "color(srgb 1 1 1 / -0.2)", "color(srgb 1 1 1 / 0)"); + + // Invalid properties + testColorFunction("Empty", "color()", "rgb(0, 0, 0)"); + testColorFunction("Bad color space", "color(banana 1 1 1)", "rgb(0, 0, 0)"); + testColorFunction("Bad Display P3 color space", "color(displayp3 1 1 1)", "rgb(0, 0, 0)"); + testColorFunction("No color space", "color(1 1 1)", "rgb(0, 0, 0)"); + testColorFunction("Too many parameters", "color(srgb 1 1 1 1)", "rgb(0, 0, 0)"); + testColorFunction("Way too many parameters", "color(srgb 1 1 1 1 1)", "rgb(0, 0, 0)"); + testColorFunction("Bad parameters", "color(srgb 1 eggs 1)", "rgb(0, 0, 0)"); + testColorFunction("Bad alpha", "color(srgb 1 1 1 / bacon)", "rgb(0, 0, 0)"); + testColorFunction("Junk after alpha", "color(srgb 1 1 1 / 1 cucumber)", "rgb(0, 0, 0)"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/interfaces-expected.txt index ecbdb9f..ce797ad5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/interfaces-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 237 tests; 216 PASS, 21 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 237 tests; 222 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS CSS Typed OM IDL test PASS CSSStyleValue interface: existence and properties of interface object PASS CSSStyleValue interface object length @@ -207,12 +207,12 @@ PASS CSSSkewX interface: existence and properties of interface prototype object PASS CSSSkewX interface: existence and properties of interface prototype object's "constructor" property PASS CSSSkewX interface: attribute ax -FAIL CSSSkewY interface: existence and properties of interface object assert_own_property: self does not have own property "CSSSkewY" expected property "CSSSkewY" missing -FAIL CSSSkewY interface object length assert_own_property: self does not have own property "CSSSkewY" expected property "CSSSkewY" missing -FAIL CSSSkewY interface object name assert_own_property: self does not have own property "CSSSkewY" expected property "CSSSkewY" missing -FAIL CSSSkewY interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CSSSkewY" expected property "CSSSkewY" missing -FAIL CSSSkewY interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CSSSkewY" expected property "CSSSkewY" missing -FAIL CSSSkewY interface: attribute ay assert_own_property: self does not have own property "CSSSkewY" expected property "CSSSkewY" missing +PASS CSSSkewY interface: existence and properties of interface object +PASS CSSSkewY interface object length +PASS CSSSkewY interface object name +PASS CSSSkewY interface: existence and properties of interface prototype object +PASS CSSSkewY interface: existence and properties of interface prototype object's "constructor" property +PASS CSSSkewY interface: attribute ay PASS CSSPerspective interface: existence and properties of interface object PASS CSSPerspective interface object length PASS CSSPerspective interface object name
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/resources/testhelper.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/resources/testhelper.js index 0099da2..91af64c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/resources/testhelper.js +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/resources/testhelper.js
@@ -57,6 +57,9 @@ case 'CSSSkewX': assert_style_value_equals(a.ax, b.ax); break; + case 'CSSSkewY': + assert_style_value_equals(a.ay, b.ay); + break; case 'CSSPerspective': assert_style_value_equals(a.length, b.length); break;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-normalization/transformvalue-normalization.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-normalization/transformvalue-normalization.tentative.html index 626c4bb7..9157ae8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-normalization/transformvalue-normalization.tentative.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-normalization/transformvalue-normalization.tentative.html
@@ -140,7 +140,7 @@ }, { cssText: 'skewY(90deg)', - expected: new CSSSkew(CSS.deg(0), CSS.deg(90)), + expected: new CSSSkewY(CSS.deg(90)), desc: 'skewY()' }, { @@ -158,13 +158,14 @@ test(t => { test_transform_normalization(t, - 'translate(1px) rotateX(90deg) perspective(1px) skew(90deg) skewX(20deg) scale3d(1, 2, 3)', + 'translate(1px) rotateX(90deg) perspective(1px) skew(90deg) skewX(20deg) skewY(30deg) scale3d(1, 2, 3)', new CSSTransformValue([ new CSSTranslate(CSS.px(1), CSS.px(0)), new CSSRotate(CSS.number(1), CSS.number(0), CSS.number(0), CSS.deg(90)), new CSSPerspective(CSS.px(1)), new CSSSkew(CSS.deg(90), CSS.deg(0)), new CSSSkewX(CSS.deg(20)), + new CSSSkewY(CSS.deg(30)), new CSSScale(CSS.number(1), CSS.number(2), CSS.number(3)), ])); }, 'Normalizing a <transform-list> returns a CSSTransformValue containing all the transforms');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-serialization/cssTransformValue.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-serialization/cssTransformValue.tentative.html index 48926ad2..dc87e81 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-serialization/cssTransformValue.tentative.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-serialization/cssTransformValue.tentative.html
@@ -55,6 +55,11 @@ desc: 'CSSSkewX' }, { + value: new CSSSkewY(CSS.deg(90)), + cssText: 'skewY(90deg)', + desc: 'CSSSkewY' + }, + { value: new CSSPerspective(CSS.px(1)), cssText: 'perspective(1px)', desc: 'CSSPerspective'
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssSkewY.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssSkewY.tentative.html new file mode 100644 index 0000000..643d2f6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssSkewY.tentative.html
@@ -0,0 +1,62 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSSSkewY tests</title> +<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#cssskewy"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../resources/testhelper.js"></script> +<script> +'use strict'; + +const gInvalidTestCases = [ + { value: 'auto', desc: 'a keyword'}, + { value: 3.14, desc: 'a double'}, + { value: 0, desc: 'a unitless zero'}, + { value: '10deg', desc: 'a string angle'}, + { value: CSS.number(10), desc: 'a number CSSUnitValue'}, + { value: CSS.s(10), desc: 'a time dimension CSSUnitValue'}, + { value: new CSSMathSum(CSS.px(1)), desc: 'a CSSMathValue of length type' }, +]; + +for (const {value, desc} of gInvalidTestCases) { + test(() => { + assert_throws(new TypeError(), () => new CSSSkewY(value)); + }, 'Constructing a CSSSkewY with ' + desc + ' throws a TypeError'); +} + +for (const {value, desc} of gInvalidTestCases) { + test(() => { + let skewY = new CSSSkewY(CSS.deg(0)); + assert_throws(new TypeError(), () => skewY.ay = value); + assert_style_value_equals(skewY.ay, CSS.deg(0)); + }, 'Updating CSSSkewY.ay with ' + desc + ' throws a TypeError'); +} + +const gValidTestCases = [ + { value: CSS.deg(-3.14), desc: 'an angle CSSUnitValue' }, + { value: new CSSMathSum(CSS.deg(1)), desc: 'a CSSMathValue of angle type' }, +]; + +for (const {value: ay, desc: ayDesc} of gValidTestCases) { + test(() => { + const skewY = new CSSSkewY(ay); + assert_equals(skewY.ay, ay); + assert_true(skewY.is2D); + }, 'CSSSkewY can be constructed from ' + ayDesc); +} + +for (const {value, desc} of gValidTestCases) { + test(() => { + let skewY = new CSSSkewY(CSS.deg(0)); + skewY.ay = value; + assert_style_value_equals(skewY.ay, value); + }, 'CSSSkewY.ay can be updated to ' + desc); +} + +test(() => { + let skewY = new CSSSkewY(CSS.deg(0)); + skewY.is2D = false; + assert_true(skewY.is2D); +}, 'Modifying skewY.is2D is a no-op'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/parse-alignment-of-root-elements.html b/third_party/WebKit/LayoutTests/fast/alignment/parse-alignment-of-root-elements.html index 16f1b84..52dd32c8 100644 --- a/third_party/WebKit/LayoutTests/fast/alignment/parse-alignment-of-root-elements.html +++ b/third_party/WebKit/LayoutTests/fast/alignment/parse-alignment-of-root-elements.html
@@ -55,19 +55,19 @@ console.log(); document.documentElement.style.justifyItems = "center"; checkValues(document.documentElement, "justifyItems", "justify-items", "center", "center"); - document.body.style.justifyItems = "auto"; + document.body.style.justifyItems = "legacy"; document.body.style.justifySelf = "auto"; - checkValues(document.body, "justifyItems", "justify-items", "auto", "normal"); + checkValues(document.body, "justifyItems", "justify-items", "legacy", "normal"); checkValues(document.body, "justifySelf", "justify-self", "auto", "auto"); - block.style.justifyItems = "auto"; + block.style.justifyItems = "legacy"; block.style.justifySelf = "auto"; - checkValues(block, "justifyItems", "justify-items", "auto", "normal"); + checkValues(block, "justifyItems", "justify-items", "legacy", "normal"); checkValues(block, "justifySelf", "justify-self", "auto", "auto"); }, "Check out how the DOM's root element justify-items's value is used to resolve its children's justify-self 'auto' values."); test(function() { - document.documentElement.style.justifyItems = "auto"; - checkValues(document.documentElement, "justifyItems", "justify-items", "auto", "normal"); + document.documentElement.style.justifyItems = "legacy"; + checkValues(document.documentElement, "justifyItems", "justify-items", "legacy", "normal"); checkValues(document.body, "justifySelf", "justify-self", "auto", "auto"); checkValues(block, "justifySelf", "justify-self", "auto", "auto"); }, "Check out how the DOM's root element deals with 'auto' value in justify-items."); @@ -75,21 +75,21 @@ test(function() { document.documentElement.style.justifyItems = "legacy center"; checkValues(document.documentElement, "justifyItems", "justify-items", "legacy center", "legacy center"); - document.body.style.justifyItems = "auto"; + document.body.style.justifyItems = "legacy"; document.body.style.justifySelf = "auto"; - checkValues(document.body, "justifyItems", "justify-items", "auto", "legacy center"); + checkValues(document.body, "justifyItems", "justify-items", "legacy", "legacy center"); checkValues(document.body, "justifySelf", "justify-self", "auto", "auto"); - block.style.justifyItems = "auto"; + block.style.justifyItems = "legacy"; block.style.justifySelf = "auto"; - checkValues(block, "justifyItems", "justify-items", "auto", "legacy center"); + checkValues(block, "justifyItems", "justify-items", "legacy", "legacy center"); checkValues(block, "justifySelf", "justify-self", "auto", "auto"); }, "Check out how the DOM's root element justify-items's value with 'legacy' keyword is used to resolve any descendant's justify-items 'auto' values."); test(function() { - document.documentElement.style.justifyItems = "auto"; - checkValues(document.body, "justifyItems", "justify-items", "auto", "normal"); + document.documentElement.style.justifyItems = "legacy"; + checkValues(document.body, "justifyItems", "justify-items", "legacy", "normal"); checkValues(document.body, "justifySelf", "justify-self", "auto", "auto"); - checkValues(block, "justifyItems", "justify-items", "auto", "normal"); + checkValues(block, "justifyItems", "justify-items", "legacy", "normal"); checkValues(block, "justifySelf", "justify-self", "auto", "auto"); }, "Check out how the DOM's root element recomputes its descendant's style when 'legacy' keyword is removed from its justify-items value."); @@ -127,22 +127,22 @@ }, "Shadow Node inherits from ShadowHost to resolve the 'auto' values for justify-self."); test(function() { - shadowHost.style.justifyItems = "auto"; + shadowHost.style.justifyItems = "legacy"; shadowNode.style.justifyItems = "right"; shadowNode.style.justifySelf = "auto"; - checkValues(shadowHost, "justifyItems", "justify-items", "auto", "normal"); + checkValues(shadowHost, "justifyItems", "justify-items", "legacy", "normal"); checkValues(shadowNode, "justifyItems", "justify-items", "right", "right"); checkValues(shadowNode, "justifySelf", "justify-self", "auto", "auto"); - checkValues(shadowHost, "justifyItems", "justify-items", "auto", "normal"); + checkValues(shadowHost, "justifyItems", "justify-items", "legacy", "normal"); document.documentElement.style.justifyItems = "legacy center"; checkValues(document.documentElement, "justifyItems", "justify-items", "legacy center", "legacy center"); - checkValues(shadowHost, "justifyItems", "justify-items", "auto", "legacy center"); + checkValues(shadowHost, "justifyItems", "justify-items", "legacy", "legacy center"); checkValues(shadowNode, "justifyItems", "justify-items", "right", "right"); checkValues(shadowNode, "justifySelf", "justify-self", "auto", "auto"); - shadowNode.style.justifyItems = "auto"; - checkValues(shadowNode, "justifyItems", "justify-items", "auto", "legacy center"); - document.documentElement.style.justifyItems = "auto"; + shadowNode.style.justifyItems = "legacy"; + checkValues(shadowNode, "justifyItems", "justify-items", "legacy", "legacy center"); + document.documentElement.style.justifyItems = "legacy"; }, "Check out how the 'legacy' keyword in justify-items propagates from the DOM Tree to the Shadow Node."); @@ -178,22 +178,22 @@ }, "Check out how justify-self uses the 'shadowHost' as 'slotted' element's parent while 'slot' is not assigned."); test(function() { - shadowHost.style.justifyItems = "auto"; + shadowHost.style.justifyItems = "legacy"; shadowNode.style.justifyItems = "right"; - checkValues(shadowHost, "justifyItems", "justify-items", "auto", "normal"); + checkValues(shadowHost, "justifyItems", "justify-items", "legacy", "normal"); checkValues(shadowNode, "justifyItems", "justify-items", "right", "right"); document.documentElement.style.justifyItems = "legacy center"; checkValues(document.documentElement, "justifyItems", "justify-items", "legacy center", "legacy center"); - checkValues(shadowHost, "justifyItems", "justify-items", "auto", "legacy center"); - slotted.style.justifyItems = "auto"; - checkValues(slotted, "justifyItems", "justify-items", "auto", "normal"); + checkValues(shadowHost, "justifyItems", "justify-items", "legacy", "legacy center"); + slotted.style.justifyItems = "legacy"; + checkValues(slotted, "justifyItems", "justify-items", "legacy", "normal"); slotted.style.justifySelf = "auto"; checkValues(slotted, "justifySelf", "justify-self", "auto", "auto"); - shadowNode.style.justifyItems = "auto"; - checkValues(shadowNode, "justifyItems", "justify-items", "auto", "legacy center"); - checkValues(slotted, "justifyItems", "justify-items", "auto", "normal"); + shadowNode.style.justifyItems = "legacy"; + checkValues(shadowNode, "justifyItems", "justify-items", "legacy", "legacy center"); + checkValues(slotted, "justifyItems", "justify-items", "legacy", "normal"); checkValues(slotted, "justifySelf", "justify-self", "auto", "auto"); - document.documentElement.style.justifyItems = "auto"; + document.documentElement.style.justifyItems = "legacy"; }, "Check out how the 'legacy' keyword in justify-items affects the 'slotted' elements while 'slot' is not assigned."); // Slot element is assigned now. @@ -228,22 +228,22 @@ }, "Check out how justify-self uses the 'slot' element's parent (Shadow Node) as 'slotted' element' s parent after the 'slot' is assigned."); test(function() { - shadowHost.style.justifyItems = "auto"; + shadowHost.style.justifyItems = "legacy"; shadowNode.style.justifyItems = "right"; - checkValues(shadowHost, "justifyItems", "justify-items", "auto", "normal"); + checkValues(shadowHost, "justifyItems", "justify-items", "legacy", "normal"); checkValues(shadowNode, "justifyItems", "justify-items", "right", "right"); document.documentElement.style.justifyItems = "legacy center"; checkValues(document.documentElement, "justifyItems", "justify-items", "legacy center", "legacy center"); - checkValues(shadowHost, "justifyItems", "justify-items", "auto", "legacy center"); - slotted.style.justifyItems = "auto"; - checkValues(slotted, "justifyItems", "justify-items", "auto", "normal"); // Shadow host is not the parent now, but ShadowNode. + checkValues(shadowHost, "justifyItems", "justify-items", "legacy", "legacy center"); + slotted.style.justifyItems = "legacy"; + checkValues(slotted, "justifyItems", "justify-items", "legacy", "normal"); // Shadow host is not the parent now, but ShadowNode. slotted.style.justifySelf = "auto"; checkValues(slotted, "justifySelf", "justify-self", "auto", "auto"); // Shadow host is not the parent now, but ShadowNode. - shadowNode.style.justifyItems = "auto"; - checkValues(shadowNode, "justifyItems", "justify-items", "auto", "legacy center"); - checkValues(slotted, "justifyItems", "justify-items", "auto", "legacy center"); // Now that shadowNode is auto, 'legacy' applies. + shadowNode.style.justifyItems = "legacy"; + checkValues(shadowNode, "justifyItems", "justify-items", "legacy", "legacy center"); + checkValues(slotted, "justifyItems", "justify-items", "legacy", "legacy center"); // Now that shadowNode is auto, 'legacy' applies. checkValues(slotted, "justifySelf", "justify-self", "auto", "auto"); // Now that shadowNode is auto, 'legacy' applies. - document.documentElement.style.justifyItems = "auto"; + document.documentElement.style.justifyItems = "legacy"; }, "Check out how the 'legacy' keyword affects the 'slotted' elements after the 'slot' is assigned."); test(function() { @@ -265,8 +265,8 @@ slot.style.justifyItems = "left"; checkValues(slot, "justifyItems", "justify-items", "left", "left"); - slot.style.justifyItems = "auto"; - checkValues(slot, "justifyItems", "justify-items", "auto", "normal"); + slot.style.justifyItems = "legacy"; + checkValues(slot, "justifyItems", "justify-items", "legacy", "normal"); slot.style.justifySelf = "left"; checkValues(slot, "justifySelf", "justify-self", "left", "left"); slot.style.justifySelf = "auto";
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/parse-justify-items.html b/third_party/WebKit/LayoutTests/fast/alignment/parse-justify-items.html index cf2411d..2e5b4a1 100644 --- a/third_party/WebKit/LayoutTests/fast/alignment/parse-justify-items.html +++ b/third_party/WebKit/LayoutTests/fast/alignment/parse-justify-items.html
@@ -245,32 +245,31 @@ element.style.justifyItems = "normal"; checkValues(element, "justifyItems", "justify-items", "normal", "normal"); - element.style.justifyItems = "auto"; - checkValues(element, "justifyItems", "justify-items", "auto", "normal"); + element.style.justifyItems = "legacy"; + checkValues(element, "justifyItems", "justify-items", "legacy", "normal"); element.style.display = "flex"; - element.style.justifyItems = "auto"; - checkValues(element, "justifyItems", "justify-items", "auto", "normal"); + element.style.justifyItems = "legacy"; + checkValues(element, "justifyItems", "justify-items", "legacy", "normal"); element.style.display = "grid"; - element.style.justifyItems = "auto"; - checkValues(element, "justifyItems", "justify-items", "auto", "normal"); + element.style.justifyItems = "legacy"; + checkValues(element, "justifyItems", "justify-items", "legacy", "normal"); element.style.justifyItems = "self-end"; checkValues(element, "justifyItems", "justify-items", "self-end", "self-end"); }, "Test getting and setting justify-items through JS"); test(function() { - document.documentElement.style.justifyItems = "auto"; - checkValues(document.documentElement, "justifyItems", "justify-items", "auto", "normal"); -}, "Test 'auto' value resolution for the root node"); + document.documentElement.style.justifyItems = "legacy"; + checkValues(document.documentElement, "justifyItems", "justify-items", "legacy", "normal"); +}, "Test 'legacy' value resolution for the root node"); test(function() { - container = document.createElement("div"); element = document.createElement("div"); - container.appendChild(element); - document.body.appendChild(container); + document.body.appendChild(element); + checkBadValues(element, "justifyItems", "justify-items", "auto"); checkBadValues(element, "justifyItems", "justify-items", "unsafe auto"); checkBadValues(element, "justifyItems", "justify-items", "auto safe"); checkBadValues(element, "justifyItems", "justify-items", "auto left"); @@ -300,7 +299,7 @@ checkBadValues(element, "justifyItems", "justify-items", "legacy right unsafe"); checkBadValues(element, "justifyItems", "justify-items", "legacy auto"); checkBadValues(element, "justifyItems", "justify-items", "legacy stretch"); - checkBadValues(element, "justifyItems", "justify-items", "legacy"); + checkBadValues(element, "justifyItems", "justify-items", "safe legacy"); checkBadValues(element, "justifyItems", "justify-items", "legacy left right"); checkBadValues(element, "justifyItems", "justify-items", "start safe"); checkBadValues(element, "justifyItems", "justify-items", "end unsafe"); @@ -331,5 +330,5 @@ checkLegacyValues("justifyItems", "justify-items", "legacy left"); checkLegacyValues("justifyItems", "justify-items", "legacy center"); checkLegacyValues("justifyItems", "justify-items", "legacy right"); -}, "Test the value 'legacy'"); +}, "Test the legacy alignment"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/parse-place-items.html b/third_party/WebKit/LayoutTests/fast/alignment/parse-place-items.html index 712bd1e9..33967a7 100644 --- a/third_party/WebKit/LayoutTests/fast/alignment/parse-place-items.html +++ b/third_party/WebKit/LayoutTests/fast/alignment/parse-place-items.html
@@ -5,9 +5,6 @@ #placeItemsNormal { place-items: normal; } -#placeItemsCenterAuto { - place-items: center auto; -} #placeItemsBaseline { place-items: baseline; } @@ -49,6 +46,9 @@ #placeItemsAuto { place-items: auto; } +#placeItemsCenterAuto { + place-items: center auto; +} #placeItemsNone { place-items: none; } @@ -74,7 +74,6 @@ <div id="log"></div> <div id="placeItemsNormal"></div> - <div id="placeItemsCenterAuto"></div> <div id="placeItemsBaseline"></div> <div id="placeItemsFirstBaseline"></div> <div id="placeItemsLastBaseline"></div> @@ -89,6 +88,7 @@ <div id="placeItemsEmpty"></div> <div id="placeItemsAuto"></div> + <div id="placeItemsCenterAuto"></div> <div id="placeItemsNone"></div> <div id="placeItemsSafe"></div> <div id="placeItemsStartSafe"></div> @@ -125,11 +125,6 @@ }, "Test getting the Computed Value of place-items's longhand properties when setting 'normal' value through CSS."); test(function() { - checkValues(placeItemsCenterAuto, "placeItems", "place-items", "", "center normal"); - checkPlaceItemsValues(placeItemsCenterAuto, "", "center", "normal"); -}, "Test getting the Computed Value of place-items's longhand properties when setting 'center auto' value through CSS."); - -test(function() { checkValues(placeItemsBaseline, "placeItems", "place-items", "", "baseline baseline"); checkPlaceItemsValues(placeItemsBaseline, "", "baseline", "baseline"); }, "Test getting the Computed Value of place-items's longhand properties when setting 'baseline' value through CSS."); @@ -187,12 +182,12 @@ test(function() { checkValues(placeItemsAuto, "placeItems", "place-items", "", "normal normal"); checkPlaceItemsValues(placeItemsAuto, "", "normal", "normal"); -}, "Test setting '' as incorrect value through CSS."); +}, "Test setting 'auto' as incorrect value through CSS."); test(function() { - checkValues(placeItemsAuto, "placeItems", "place-items", "", "normal normal"); - checkPlaceItemsValues(placeItemsAuto, "", "normal", "normal"); -}, "Test setting 'auto' as incorrect value through CSS."); + checkValues(placeItemsCenterAuto, "placeItems", "place-items", "", "normal normal"); + checkPlaceItemsValues(placeItemsCenterAuto, "", "normal", "normal"); +}, "Test setting 'center auto' as incorrect value through CSS."); test(function() { checkValues(placeItemsNone, "placeItems", "place-items", "", "normal normal"); @@ -227,7 +222,11 @@ }, "Test setting values through JS."); test(function() { + checkPlaceItemsValuesBadJS("auto"); checkPlaceItemsValuesBadJS("auto normal"); + checkPlaceItemsValuesBadJS("center auto"); + checkPlaceItemsValuesBadJS("legacy"); + checkPlaceItemsValuesBadJS("left legacy"); checkPlaceItemsValuesBadJS("space-between"); checkPlaceItemsValuesBadJS("center safe"); checkPlaceItemsValuesBadJS("center self-start center");
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll-overflow-hidden.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll-overflow-hidden.html new file mode 100644 index 0000000..f277464 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll-overflow-hidden.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<style> + +body { overflow: hidden; } +#space { height: 2000px; } + +</style> +<div id="space"></div> +<script> + +async_test(t => { + onscroll = t.step_func_done(() => { + assert_true(scrollY > 0); + }); + scroll({behavior: "smooth", top: 500}); +}, 'scroll'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/capitalize-boundaries-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/capitalize-boundaries-expected.png new file mode 100644 index 0000000..87cec1d5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/capitalize-boundaries-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/capitalize-boundaries-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/capitalize-boundaries-expected.txt new file mode 100644 index 0000000..439aae2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/capitalize-boundaries-expected.txt
@@ -0,0 +1,335 @@ +layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 1286 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 785x1286 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutNGBlockFlow {HTML} at (0,0) size 785x1286 + LayoutNGBlockFlow {BODY} at (8,8) size 769x1270 + LayoutNGBlockFlow (anonymous) at (0,0) size 769x100 + LayoutText {#text} at (0,0) size 346x19 + text run at (0,0) width 346: "This test was provided by open-source contributors on " + LayoutInline {A} at (0,0) size 53x19 [color=#0000EE] + LayoutText {#text} at (346,0) size 53x19 + text run at (346,0) width 53: "Bugzilla" + LayoutText {#text} at (399,0) size 740x79 + text run at (399,0) width 321: ". Currently, the \"Browser rendering\" results are not" + text run at (0,20) width 740: "expected to match the \"Correct output sample\" results. In fact, I do not entirely agree with all of the given test cases in" + text run at (0,40) width 727: "terms of their expected results, nor do I think that the browser should yet be expected to match all of the cases in the" + text run at (0,60) width 465: "different languages, but I am (at least temporarily) adding the test anyway." + LayoutBR {BR} at (464,60) size 0x0 + LayoutBR {BR} at (0,80) size 0x0 + LayoutTable {TABLE} at (0,100) size 769x390 + LayoutBlockFlow {CAPTION} at (0,0) size 769x20 + LayoutText {#text} at (345,0) size 79x19 + text run at (345,0) width 79: "Input source" + LayoutTableSection {TBODY} at (0,20) size 769x370 + LayoutTableRow {TR} at (0,2) size 769x64 + LayoutNGTableCell {TH} at (2,22) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (2,22) size 49x19 + text run at (2,22) width 49: "generic" + LayoutNGTableCell {TD} at (57,2) size 710x64 [border: (1px solid #EEEEEE)] [r=0 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 705x59 + text run at (2,2) width 664: "lip\x{AD}smackin\x{AD}thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin\x{AD}lip\x{AD}" + text run at (665,2) width 6: "-" + text run at (2,22) width 700: "smackin\x{AD}thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin\x{AD}lip\x{AD}smackin\x{AD}" + text run at (701,22) width 6: "-" + text run at (2,42) width 580: "thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin" + LayoutTableRow {TR} at (0,68) size 769x24 + LayoutNGTableCell {TH} at (2,68) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (19,2) size 15x19 + text run at (19,2) width 15: "cy" + LayoutNGTableCell {TD} at (57,68) size 710x24 [border: (1px solid #EEEEEE)] [r=1 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 24x19 + text run at (2,2) width 24: "\x{175}yl" + LayoutTableRow {TR} at (0,94) size 769x24 + LayoutNGTableCell {TH} at (2,94) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=2 c=0 rs=1 cs=1] + LayoutText {#text} at (21,2) size 11x19 + text run at (21,2) width 11: "el" + LayoutNGTableCell {TD} at (57,94) size 710x24 [border: (1px solid #EEEEEE)] [r=2 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 204x19 + text run at (2,2) width 204: "\x{3B3}\x{3B5}\x{3C9}\x{3B3}\x{3C1}\x{3B1}\x{3C6}\x{3B9}\x{3BA}\x{3AC}\x{2010}\x{3C3}\x{3C5}\x{3C3}\x{3C7}\x{3B5}\x{3C4}\x{3B9}\x{3C3}\x{3BC}\x{3AD}\x{3BD}\x{3B5}\x{3C2} \x{3AE}\x{3C4}\x{3B1}" + LayoutTableRow {TR} at (0,120) size 769x64 + LayoutNGTableCell {TH} at (2,140) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=3 c=0 rs=1 cs=1] + LayoutText {#text} at (18,22) size 17x19 + text run at (18,22) width 17: "en" + LayoutNGTableCell {TD} at (57,120) size 710x64 [border: (1px solid #EEEEEE)] [r=3 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 425x19 + text run at (2,2) width 425: "'cept nut'in safari\x{2019}s \x{2018}sure\x{2019} nai\x{308}ve r\x{E9}sum\x{E9}\x{2014}h\x{E1}c\x{30C}ek full\x{2010}time one-to-one" + LayoutBR {BR} at (426,2) size 0x0 + LayoutText {#text} at (2,22) size 318x19 + text run at (2,22) width 318: "\"newcastle\x{2011}upon\x{2011}tyne\" washington\x{2011}on\x{2011}the\x{2011}brazos" + LayoutBR {BR} at (320,22) size 0x0 + LayoutInline {SPAN} at (0,0) size 31x19 + LayoutText {#text} at (2,42) size 31x19 + text run at (2,42) width 31: "earth" + LayoutText {#text} at (33,42) size 73x19 + text run at (33,42) width 73: "quake earth" + LayoutInline {SPAN} at (0,0) size 37x19 + LayoutText {#text} at (106,42) size 37x19 + text run at (106,42) width 37: "worm" + LayoutText {#text} at (143,42) size 4x19 + text run at (143,42) width 4: " " + LayoutInline {SPAN} at (0,0) size 42x19 + LayoutText {#text} at (147,42) size 42x19 + text run at (147,42) width 42: "cheese" + LayoutInline {SPAN} at (0,0) size 41x19 + LayoutText {#text} at (189,42) size 41x19 + text run at (189,42) width 41: "burger" + LayoutText {#text} at (229,42) size 117x19 + text run at (229,42) width 117: " [house] ~six -big-" + LayoutTableRow {TR} at (0,186) size 769x24 + LayoutNGTableCell {TH} at (2,186) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=4 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "es" + LayoutNGTableCell {TD} at (57,186) size 710x24 [border: (1px solid #EEEEEE)] [r=4 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 63x19 + text run at (2,2) width 63: "\x{A1}jalape\x{F1}o!" + LayoutTableRow {TR} at (0,212) size 769x26 + LayoutNGTableCell {TH} at (2,213) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=5 c=0 rs=1 cs=1] + LayoutText {#text} at (20,3) size 13x19 + text run at (20,3) width 13: "fr" + LayoutNGTableCell {TD} at (57,212) size 710x26.44 [border: (1px solid #EEEEEE)] [r=5 c=1 rs=1 cs=1] + LayoutText {#text} at (2,4) size 207x20 + text run at (2,4) width 207: "quelqu'un l\x{2019}amour t'appelles\x{2011}tu 3" + LayoutInline {SUP} at (0,0) size 22x15 + LayoutText {#text} at (209,2) size 22x15 + text run at (209,2) width 22: "eme" + LayoutTableRow {TR} at (0,240) size 769x24 + LayoutNGTableCell {TH} at (2,240) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=6 c=0 rs=1 cs=1] + LayoutText {#text} at (17,2) size 19x19 + text run at (17,2) width 19: "hu" + LayoutNGTableCell {TD} at (57,240) size 710x24 [border: (1px solid #EEEEEE)] [r=6 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 109x19 + text run at (2,2) width 109: "11-ei london\x{2011}ban" + LayoutTableRow {TR} at (0,266) size 769x24 + LayoutNGTableCell {TH} at (2,266) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=7 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "nl" + LayoutNGTableCell {TD} at (57,266) size 710x24 [border: (1px solid #EEEEEE)] [r=7 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 69x19 + text run at (2,2) width 69: "'s ochtends" + LayoutTableRow {TR} at (0,292) size 769x24 + LayoutNGTableCell {TH} at (2,292) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=8 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "pl" + LayoutNGTableCell {TD} at (57,292) size 710x24 [border: (1px solid #EEEEEE)] [r=8 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 92x19 + text run at (2,2) width 92: "wzi\x{119}\x{142}a bie\x{17C}\x{105}ce" + LayoutTableRow {TR} at (0,318) size 769x24 + LayoutNGTableCell {TH} at (2,318) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=9 c=0 rs=1 cs=1] + LayoutText {#text} at (18,2) size 17x19 + text run at (18,2) width 17: "ru" + LayoutNGTableCell {TD} at (57,318) size 710x24 [border: (1px solid #EEEEEE)] [r=9 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 193x19 + text run at (2,2) width 193: "\x{43D}\x{44C}\x{44E}-\x{439}\x{43E}\x{440}\x{43A} 1990-\x{445} 14-vii-1789" + LayoutTableRow {TR} at (0,344) size 769x24 + LayoutNGTableCell {TH} at (2,344) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=10 c=0 rs=1 cs=1] + LayoutText {#text} at (17,2) size 19x19 + text run at (17,2) width 19: "tlh" + LayoutNGTableCell {TD} at (57,344) size 710x24 [border: (1px solid #EEEEEE)] [r=10 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 187x19 + text run at (2,2) width 187: "tlhIngan Hol wa''uy' loghqam" + LayoutTable {TABLE} at (0,490) size 769x390 + LayoutBlockFlow {CAPTION} at (0,0) size 769x20 + LayoutText {#text} at (315,0) size 139x19 + text run at (315,0) width 139: "Correct output sample" + LayoutTableSection {TBODY} at (0,20) size 769x370 + LayoutTableRow {TR} at (0,2) size 769x64 + LayoutNGTableCell {TH} at (2,22) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (2,22) size 49x19 + text run at (2,22) width 49: "generic" + LayoutNGTableCell {TD} at (57,2) size 710x64 [border: (1px solid #EEEEEE)] [r=0 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 705x59 + text run at (2,2) width 670: "Lip\x{AD}smackin\x{AD}thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin\x{AD}lip\x{AD}" + text run at (671,2) width 6: "-" + text run at (2,22) width 700: "smackin\x{AD}thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin\x{AD}lip\x{AD}smackin\x{AD}" + text run at (701,22) width 6: "-" + text run at (2,42) width 580: "thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin" + LayoutTableRow {TR} at (0,68) size 769x24 + LayoutNGTableCell {TH} at (2,68) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (19,2) size 15x19 + text run at (19,2) width 15: "cy" + LayoutNGTableCell {TD} at (57,68) size 710x24 [border: (1px solid #EEEEEE)] [r=1 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 27x19 + text run at (2,2) width 27: "\x{174}yl" + LayoutTableRow {TR} at (0,94) size 769x24 + LayoutNGTableCell {TH} at (2,94) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=2 c=0 rs=1 cs=1] + LayoutText {#text} at (21,2) size 11x19 + text run at (21,2) width 11: "el" + LayoutNGTableCell {TD} at (57,94) size 710x24 [border: (1px solid #EEEEEE)] [r=2 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 211x19 + text run at (2,2) width 211: "\x{393}\x{3B5}\x{3C9}\x{3B3}\x{3C1}\x{3B1}\x{3C6}\x{3B9}\x{3BA}\x{3AC}\x{2010}\x{3A3}\x{3C5}\x{3C3}\x{3C7}\x{3B5}\x{3C4}\x{3B9}\x{3C3}\x{3BC}\x{3AD}\x{3BD}\x{3B5}\x{3C2} \x{389}\x{3C4}\x{3B1}" + LayoutTableRow {TR} at (0,120) size 769x64 + LayoutNGTableCell {TH} at (2,140) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=3 c=0 rs=1 cs=1] + LayoutText {#text} at (18,22) size 17x19 + text run at (18,22) width 17: "en" + LayoutNGTableCell {TD} at (57,120) size 710x64 [border: (1px solid #EEEEEE)] [r=3 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 465x19 + text run at (2,2) width 465: "'Cept Nut'in Safari\x{2019}s \x{2018}Sure\x{2019} Na\x{EF}ve R\x{E9}sum\x{E9}\x{2014}H\x{E1}\x{10D}ek Full\x{2010}time One-to-One" + LayoutBR {BR} at (466,2) size 0x0 + LayoutText {#text} at (2,22) size 330x19 + text run at (2,22) width 330: "\"Newcastle-upon-Tyne\" Washington\x{2011}on\x{2011}the\x{2011}Brazos" + LayoutBR {BR} at (331,22) size 0x0 + LayoutText {#text} at (2,42) size 364x19 + text run at (2,42) width 364: "Earthquake Earthworm Cheeseburger [House] ~Six -Big-" + LayoutTableRow {TR} at (0,186) size 769x24 + LayoutNGTableCell {TH} at (2,186) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=4 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "es" + LayoutNGTableCell {TD} at (57,186) size 710x24 [border: (1px solid #EEEEEE)] [r=4 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 65x19 + text run at (2,2) width 65: "\x{A1}Jalape\x{F1}o!" + LayoutTableRow {TR} at (0,212) size 769x26 + LayoutNGTableCell {TH} at (2,213) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=5 c=0 rs=1 cs=1] + LayoutText {#text} at (20,3) size 13x19 + text run at (20,3) width 13: "fr" + LayoutNGTableCell {TD} at (57,212) size 710x26.44 [border: (1px solid #EEEEEE)] [r=5 c=1 rs=1 cs=1] + LayoutText {#text} at (2,4) size 227x20 + text run at (2,4) width 227: "Quelqu'un l\x{2019}Amour t'Appelles\x{2011}Tu 3" + LayoutInline {SUP} at (0,0) size 23x15 + LayoutText {#text} at (228,2) size 23x15 + text run at (228,2) width 23: "eme" + LayoutTableRow {TR} at (0,240) size 769x24 + LayoutNGTableCell {TH} at (2,240) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=6 c=0 rs=1 cs=1] + LayoutText {#text} at (17,2) size 19x19 + text run at (17,2) width 19: "hu" + LayoutNGTableCell {TD} at (57,240) size 710x24 [border: (1px solid #EEEEEE)] [r=6 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 115x19 + text run at (2,2) width 115: "11-ei London\x{2011}ban" + LayoutTableRow {TR} at (0,266) size 769x24 + LayoutNGTableCell {TH} at (2,266) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=7 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "nl" + LayoutNGTableCell {TD} at (57,266) size 710x24 [border: (1px solid #EEEEEE)] [r=7 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 73x19 + text run at (2,2) width 73: "'s Ochtends" + LayoutTableRow {TR} at (0,292) size 769x24 + LayoutNGTableCell {TH} at (2,292) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=8 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "pl" + LayoutNGTableCell {TD} at (57,292) size 710x24 [border: (1px solid #EEEEEE)] [r=8 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 98x19 + text run at (2,2) width 98: "Wzi\x{119}\x{142}a Bie\x{17C}\x{105}ce" + LayoutTableRow {TR} at (0,318) size 769x24 + LayoutNGTableCell {TH} at (2,318) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=9 c=0 rs=1 cs=1] + LayoutText {#text} at (18,2) size 17x19 + text run at (18,2) width 17: "ru" + LayoutNGTableCell {TD} at (57,318) size 710x24 [border: (1px solid #EEEEEE)] [r=9 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 199x19 + text run at (2,2) width 199: "\x{41D}\x{44C}\x{44E}-\x{419}\x{43E}\x{440}\x{43A} 1990-\x{445} 14-vii-1789" + LayoutTableRow {TR} at (0,344) size 769x24 + LayoutNGTableCell {TH} at (2,344) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=10 c=0 rs=1 cs=1] + LayoutText {#text} at (17,2) size 19x19 + text run at (17,2) width 19: "tlh" + LayoutNGTableCell {TD} at (57,344) size 710x24 [border: (1px solid #EEEEEE)] [r=10 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 187x19 + text run at (2,2) width 187: "tlhIngan Hol wa''uy' loghqam" + LayoutTable {TABLE} at (0,880) size 769x390 + LayoutBlockFlow {CAPTION} at (0,0) size 769x20 + LayoutText {#text} at (325,0) size 119x19 + text run at (325,0) width 119: "Browser rendering" + LayoutTableSection {TBODY} at (0,20) size 769x370 + LayoutTableRow {TR} at (0,2) size 769x64 + LayoutNGTableCell {TH} at (2,22) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (2,22) size 49x19 + text run at (2,22) width 49: "generic" + LayoutNGTableCell {TD} at (57,2) size 710x64 [border: (1px solid #EEEEEE)] [r=0 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 705x59 + text run at (2,2) width 670: "Lip\x{AD}smackin\x{AD}thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin\x{AD}lip\x{AD}" + text run at (671,2) width 6: "-" + text run at (2,22) width 700: "smackin\x{AD}thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin\x{AD}lip\x{AD}smackin\x{AD}" + text run at (701,22) width 6: "-" + text run at (2,42) width 580: "thirst\x{AD}quenchin\x{AD}acetastin\x{AD}motivatin\x{AD}good\x{AD}buzzin\x{AD}cool\x{AD}talkin\x{AD}high\x{AD}walkin\x{AD}fast\x{AD}livin\x{AD}ever\x{AD}givin\x{AD}cool\x{AD}fizzin" + LayoutTableRow {TR} at (0,68) size 769x24 + LayoutNGTableCell {TH} at (2,68) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=1 c=0 rs=1 cs=1] + LayoutText {#text} at (19,2) size 15x19 + text run at (19,2) width 15: "cy" + LayoutNGTableCell {TD} at (57,68) size 710x24 [border: (1px solid #EEEEEE)] [r=1 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 27x19 + text run at (2,2) width 27: "\x{174}yl" + LayoutTableRow {TR} at (0,94) size 769x24 + LayoutNGTableCell {TH} at (2,94) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=2 c=0 rs=1 cs=1] + LayoutText {#text} at (21,2) size 11x19 + text run at (21,2) width 11: "el" + LayoutNGTableCell {TD} at (57,94) size 710x24 [border: (1px solid #EEEEEE)] [r=2 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 211x19 + text run at (2,2) width 211: "\x{393}\x{3B5}\x{3C9}\x{3B3}\x{3C1}\x{3B1}\x{3C6}\x{3B9}\x{3BA}\x{3AC}\x{2010}\x{3A3}\x{3C5}\x{3C3}\x{3C7}\x{3B5}\x{3C4}\x{3B9}\x{3C3}\x{3BC}\x{3AD}\x{3BD}\x{3B5}\x{3C2} \x{389}\x{3C4}\x{3B1}" + LayoutTableRow {TR} at (0,120) size 769x64 + LayoutNGTableCell {TH} at (2,140) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=3 c=0 rs=1 cs=1] + LayoutText {#text} at (18,22) size 17x19 + text run at (18,22) width 17: "en" + LayoutNGTableCell {TD} at (57,120) size 710x64 [border: (1px solid #EEEEEE)] [r=3 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 476x19 + text run at (2,2) width 476: "'Cept Nut'in Safari\x{2019}s \x{2018}Sure\x{2019} Nai\x{308}ve R\x{E9}sum\x{E9}\x{2014}H\x{E1}c\x{30C}ek Full\x{2010}Time One-To-One" + LayoutBR {BR} at (477,2) size 0x0 + LayoutText {#text} at (2,22) size 346x19 + text run at (2,22) width 346: "\"Newcastle\x{2011}Upon\x{2011}Tyne\" Washington\x{2011}On\x{2011}The\x{2011}Brazos" + LayoutBR {BR} at (347,22) size 0x0 + LayoutInline {SPAN} at (0,0) size 34x19 + LayoutText {#text} at (2,42) size 34x19 + text run at (2,42) width 34: "Earth" + LayoutText {#text} at (36,42) size 76x19 + text run at (36,42) width 76: "quake Earth" + LayoutInline {SPAN} at (0,0) size 37x19 + LayoutText {#text} at (112,42) size 37x19 + text run at (112,42) width 37: "worm" + LayoutText {#text} at (149,42) size 4x19 + text run at (149,42) width 4: " " + LayoutInline {SPAN} at (0,0) size 46x19 + LayoutText {#text} at (153,42) size 46x19 + text run at (153,42) width 46: "Cheese" + LayoutInline {SPAN} at (0,0) size 41x19 + LayoutText {#text} at (199,42) size 41x19 + text run at (199,42) width 41: "burger" + LayoutText {#text} at (239,42) size 127x19 + text run at (239,42) width 127: " [House] ~Six -Big-" + LayoutTableRow {TR} at (0,186) size 769x24 + LayoutNGTableCell {TH} at (2,186) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=4 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "es" + LayoutNGTableCell {TD} at (57,186) size 710x24 [border: (1px solid #EEEEEE)] [r=4 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 65x19 + text run at (2,2) width 65: "\x{A1}Jalape\x{F1}o!" + LayoutTableRow {TR} at (0,212) size 769x26 + LayoutNGTableCell {TH} at (2,213) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=5 c=0 rs=1 cs=1] + LayoutText {#text} at (20,3) size 13x19 + text run at (20,3) width 13: "fr" + LayoutNGTableCell {TD} at (57,212) size 710x26.44 [border: (1px solid #EEEEEE)] [r=5 c=1 rs=1 cs=1] + LayoutText {#text} at (2,4) size 227x20 + text run at (2,4) width 227: "Quelqu'un L\x{2019}amour T'appelles\x{2011}Tu 3" + LayoutInline {SUP} at (0,0) size 23x15 + LayoutText {#text} at (228,2) size 23x15 + text run at (228,2) width 23: "eme" + LayoutTableRow {TR} at (0,240) size 769x24 + LayoutNGTableCell {TH} at (2,240) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=6 c=0 rs=1 cs=1] + LayoutText {#text} at (17,2) size 19x19 + text run at (17,2) width 19: "hu" + LayoutNGTableCell {TD} at (57,240) size 710x24 [border: (1px solid #EEEEEE)] [r=6 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 121x19 + text run at (2,2) width 121: "11-Ei London\x{2011}Ban" + LayoutTableRow {TR} at (0,266) size 769x24 + LayoutNGTableCell {TH} at (2,266) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=7 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "nl" + LayoutNGTableCell {TD} at (57,266) size 710x24 [border: (1px solid #EEEEEE)] [r=7 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 76x19 + text run at (2,2) width 76: "'S Ochtends" + LayoutTableRow {TR} at (0,292) size 769x24 + LayoutNGTableCell {TH} at (2,292) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=8 c=0 rs=1 cs=1] + LayoutText {#text} at (20,2) size 13x19 + text run at (20,2) width 13: "pl" + LayoutNGTableCell {TD} at (57,292) size 710x24 [border: (1px solid #EEEEEE)] [r=8 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 98x19 + text run at (2,2) width 98: "Wzi\x{119}\x{142}a Bie\x{17C}\x{105}ce" + LayoutTableRow {TR} at (0,318) size 769x24 + LayoutNGTableCell {TH} at (2,318) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=9 c=0 rs=1 cs=1] + LayoutText {#text} at (18,2) size 17x19 + text run at (18,2) width 17: "ru" + LayoutNGTableCell {TD} at (57,318) size 710x24 [border: (1px solid #EEEEEE)] [r=9 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 207x19 + text run at (2,2) width 207: "\x{41D}\x{44C}\x{44E}-\x{419}\x{43E}\x{440}\x{43A} 1990-\x{425} 14-Vii-1789" + LayoutTableRow {TR} at (0,344) size 769x24 + LayoutNGTableCell {TH} at (2,344) size 53x24 [bgcolor=#F8F8F8] [border: (1px solid #EEEEEE)] [r=10 c=0 rs=1 cs=1] + LayoutText {#text} at (17,2) size 19x19 + text run at (17,2) width 19: "tlh" + LayoutNGTableCell {TD} at (57,344) size 710x24 [border: (1px solid #EEEEEE)] [r=10 c=1 rs=1 cs=1] + LayoutText {#text} at (2,2) size 205x19 + text run at (2,2) width 205: "TlhIngan Hol Wa''Uy' Loghqam"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png index 117c823..e4eedfb 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.txt new file mode 100644 index 0000000..c4d31dc --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.txt
@@ -0,0 +1,17 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x116 + LayoutNGBlockFlow {HTML} at (0,0) size 800x116 + LayoutNGBlockFlow {BODY} at (8,16) size 784x92 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 479x19 + text run at (0,0) width 479: "crbug.com/634445: Rtl text in a ltr flow should truncate the text left-to-right." + LayoutNGBlockFlow {P} at (0,36) size 784x20 + LayoutText {#text} at (0,0) size 404x19 + text run at (0,0) width 404: "You should see an underline beneath the text but not the ellipsis." +layer at (8,88) size 350x20 + LayoutNGBlockFlow {DIV} at (0,72) size 350x20 + LayoutText {#text} at (6,0) size 344x19 + text run at (6,0) width 16: "\x{2026}" + text run at (22,0) width 244: " \x{5D9}\x{5E0}\x{5D8}\x{5E8}\x{5E0}\x{5D8} \x{5D5}\x{5DB}\x{5D5}' \x{5D1}\x{5DE}\x{5E7}\x{5D5}\x{5DD} \x{5D4}\x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D4}\x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9} \x{5D4}\x{5E1}\x{5D5}\x{5E4}\x{5D9}\x{5E2}\x{5D3} " + text run at (266,0) width 84: "Lorem ipsum"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-expected.png deleted file mode 100644 index a1362791..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-expected.txt new file mode 100644 index 0000000..b7e6e33 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-expected.txt
@@ -0,0 +1,17 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x116 + LayoutNGBlockFlow {HTML} at (0,0) size 800x116 + LayoutNGBlockFlow {BODY} at (8,16) size 784x92 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 479x19 + text run at (0,0) width 479: "crbug.com/634445: Rtl text in a rtl flow should truncate the text right-to-left." + LayoutNGBlockFlow {P} at (0,36) size 784x20 + LayoutText {#text} at (0,0) size 286x19 + text run at (0,0) width 286: "You should see an underline beneath the text." +layer at (8,88) size 125x20 + LayoutNGBlockFlow {DIV} at (0,72) size 125x20 + LayoutText {#text} at (3,0) size 122x19 + text run at (3,0) width 16: "\x{2026}" + text run at (19,0) width 64: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}" + text run at (83,0) width 42: "Lorem"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/stroking-decorations-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/stroking-decorations-expected.png new file mode 100644 index 0000000..f2b2ea93 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/stroking-decorations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/stroking-decorations-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/stroking-decorations-expected.txt new file mode 100644 index 0000000..80ce5e1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/stroking-decorations-expected.txt
@@ -0,0 +1,17 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x472 + LayoutNGBlockFlow {HTML} at (0,0) size 800x472 + LayoutNGBlockFlow {BODY} at (8,8) size 784x456 + LayoutNGBlockFlow {DIV} at (0,0) size 784x152 [textFillColor=#800080] [textStrokeWidth=2.00] + LayoutText {#text} at (0,1) size 759x149 + text run at (0,1) width 616: "Purple\x{300} fill, black stroke," + text run at (0,77) width 759: "complex text, black underline" + LayoutNGBlockFlow {DIV} at (0,152) size 784x152 [textStrokeColor=#FFA500] [textStrokeWidth=1.33] + LayoutText {#text} at (0,1) size 636x149 + text run at (0,1) width 636: "Orange stroke, black fill," + text run at (0,77) width 414: "orange overline." + LayoutNGBlockFlow {DIV} at (0,304) size 784x152 [textFillColor=#0000FF] [textStrokeWidth=1.33] + LayoutText {#text} at (0,1) size 596x149 + text run at (0,1) width 596: "No stroke, blue fill, red" + text run at (0,77) width 590: "shadow, blue underline"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/sub-pixel/text-scaling-pixel-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/sub-pixel/text-scaling-pixel-expected.png index 334cb16..4f99aade 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/sub-pixel/text-scaling-pixel-expected.png +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/sub-pixel/text-scaling-pixel-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/sub-pixel/text-scaling-pixel-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/sub-pixel/text-scaling-pixel-expected.txt new file mode 100644 index 0000000..acce51e --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/sub-pixel/text-scaling-pixel-expected.txt
@@ -0,0 +1,990 @@ +layer at (0,0) size 800x600 scrollHeight 1353 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x1353 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x1353 + LayoutNGBlockFlow {BODY} at (8,8) size 784x1337 + LayoutNGBlockFlow {SECTION} at (0,0) size 785.55x1321 + LayoutNGBlockFlow {H1} at (0,0) size 785.55x27 + LayoutText {#text} at (0,0) size 281x26 + text run at (0,0) width 281: "Font Size Scaling Pixel Test" + LayoutNGBlockFlow {P} at (0,31) size 785.55x20 + LayoutText {#text} at (0,0) size 766x19 + text run at (0,0) width 766: "Size of the text should scale smoothly. Reported width should be within 0.02px of that of the highlighted reference row." + LayoutNGBlockFlow {DIV} at (0,55) size 785.55x1266 + LayoutNGBlockFlow {DIV} at (0,0) size 785.55x14 [border: none (1px solid #000000) none] + LayoutNGBlockFlow {DIV} at (0,0) size 65x13 + LayoutText {#text} at (17,0) size 43x13 + text run at (17,0) width 43: "Font Size" + LayoutNGBlockFlow {DIV} at (65,0) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "Width" + LayoutNGBlockFlow {DIV} at (130,0) size 65x13 + LayoutText {#text} at (9,0) size 51x13 + text run at (9,0) width 51: "Normalized" + LayoutNGBlockFlow {DIV} at (195,0) size 65x13 + LayoutText {#text} at (45,0) size 15x13 + text run at (45,0) width 15: "Diff" + LayoutInline {SPAN} at (0,0) size 36x13 + LayoutText {#text} at (260,0) size 36x13 + text run at (260,0) width 36: "Content" + LayoutNGBlockFlow {DIV} at (0,14) size 785.55x13 + LayoutNGBlockFlow {DIV} at (0,0) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "10.00" + LayoutNGBlockFlow {DIV} at (65,0) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "212.34" + LayoutNGBlockFlow {DIV} at (130,0) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,0) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 213x13 + LayoutText {#text} at (260,0) size 213x13 + text run at (260,0) width 213: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,27) size 785.55x13 + LayoutNGBlockFlow {DIV} at (0,0) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "10.25" + LayoutNGBlockFlow {DIV} at (65,0) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "217.66" + LayoutNGBlockFlow {DIV} at (130,0) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,0) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 218x13 + LayoutText {#text} at (260,0) size 218x13 + text run at (260,0) width 218: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,40) size 785.55x14 + LayoutNGBlockFlow {DIV} at (0,1) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "10.50" + LayoutNGBlockFlow {DIV} at (65,1) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "222.97" + LayoutNGBlockFlow {DIV} at (130,1) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,1) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.01" + LayoutInline {SPAN} at (0,0) size 223x14 + LayoutText {#text} at (260,0) size 223x14 + text run at (260,0) width 223: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,54) size 785.55x14 + LayoutNGBlockFlow {DIV} at (0,1) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "10.75" + LayoutNGBlockFlow {DIV} at (65,1) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "228.27" + LayoutNGBlockFlow {DIV} at (130,1) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,1) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 229x14 + LayoutText {#text} at (260,0) size 229x14 + text run at (260,0) width 229: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,68) size 785.55x14 + LayoutNGBlockFlow {DIV} at (0,1) size 65x13 + LayoutText {#text} at (35,0) size 25x13 + text run at (35,0) width 25: "11.00" + LayoutNGBlockFlow {DIV} at (65,1) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "233.58" + LayoutNGBlockFlow {DIV} at (130,1) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,1) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 234x14 + LayoutText {#text} at (260,0) size 234x14 + text run at (260,0) width 234: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,82) size 785.55x14 + LayoutNGBlockFlow {DIV} at (0,1) size 65x13 + LayoutText {#text} at (35,0) size 25x13 + text run at (35,0) width 25: "11.25" + LayoutNGBlockFlow {DIV} at (65,1) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "238.89" + LayoutNGBlockFlow {DIV} at (130,1) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,1) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 239x14 + LayoutText {#text} at (260,0) size 239x14 + text run at (260,0) width 239: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,96) size 785.55x15 + LayoutNGBlockFlow {DIV} at (0,2) size 65x13 + LayoutText {#text} at (35,0) size 25x13 + text run at (35,0) width 25: "11.50" + LayoutNGBlockFlow {DIV} at (65,2) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "244.20" + LayoutNGBlockFlow {DIV} at (130,2) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,2) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.01" + LayoutInline {SPAN} at (0,0) size 245x15 + LayoutText {#text} at (260,0) size 245x15 + text run at (260,0) width 245: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,111) size 785.55x15 + LayoutNGBlockFlow {DIV} at (0,2) size 65x13 + LayoutText {#text} at (35,0) size 25x13 + text run at (35,0) width 25: "11.75" + LayoutNGBlockFlow {DIV} at (65,2) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "249.50" + LayoutNGBlockFlow {DIV} at (130,2) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,2) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 250x15 + LayoutText {#text} at (260,0) size 250x15 + text run at (260,0) width 250: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,126) size 785.55x15 [bgcolor=#FBFCC5] + LayoutNGBlockFlow {DIV} at (0,2) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "12.00" + LayoutNGBlockFlow {DIV} at (65,2) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (130,2) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,2) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 255x15 + LayoutText {#text} at (260,0) size 255x15 + text run at (260,0) width 255: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,141) size 785.55x15 + LayoutNGBlockFlow {DIV} at (0,2) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "12.25" + LayoutNGBlockFlow {DIV} at (65,2) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "260.13" + LayoutNGBlockFlow {DIV} at (130,2) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,2) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 261x15 + LayoutText {#text} at (260,0) size 261x15 + text run at (260,0) width 261: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,156) size 785.55x16 + LayoutNGBlockFlow {DIV} at (0,3) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "12.50" + LayoutNGBlockFlow {DIV} at (65,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "265.44" + LayoutNGBlockFlow {DIV} at (130,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,3) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.01" + LayoutInline {SPAN} at (0,0) size 266x16 + LayoutText {#text} at (260,0) size 266x16 + text run at (260,0) width 266: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,172) size 785.55x16 + LayoutNGBlockFlow {DIV} at (0,3) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "12.75" + LayoutNGBlockFlow {DIV} at (65,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "270.73" + LayoutNGBlockFlow {DIV} at (130,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,3) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 271x16 + LayoutText {#text} at (260,0) size 271x16 + text run at (260,0) width 271: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,188) size 785.55x16 + LayoutNGBlockFlow {DIV} at (0,3) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "13.00" + LayoutNGBlockFlow {DIV} at (65,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "276.05" + LayoutNGBlockFlow {DIV} at (130,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,3) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 277x16 + LayoutText {#text} at (260,0) size 277x16 + text run at (260,0) width 277: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,204) size 785.55x16 + LayoutNGBlockFlow {DIV} at (0,3) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "13.25" + LayoutNGBlockFlow {DIV} at (65,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "281.36" + LayoutNGBlockFlow {DIV} at (130,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,3) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 282x16 + LayoutText {#text} at (260,0) size 282x16 + text run at (260,0) width 282: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,220) size 785.55x16 + LayoutNGBlockFlow {DIV} at (0,3) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "13.50" + LayoutNGBlockFlow {DIV} at (65,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "286.67" + LayoutNGBlockFlow {DIV} at (130,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,3) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.01" + LayoutInline {SPAN} at (0,0) size 287x16 + LayoutText {#text} at (260,0) size 287x16 + text run at (260,0) width 287: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,236) size 785.55x16 + LayoutNGBlockFlow {DIV} at (0,3) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "13.75" + LayoutNGBlockFlow {DIV} at (65,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "291.97" + LayoutNGBlockFlow {DIV} at (130,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,3) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 292x16 + LayoutText {#text} at (260,0) size 292x16 + text run at (260,0) width 292: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,252) size 785.55x16 + LayoutNGBlockFlow {DIV} at (0,3) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "14.00" + LayoutNGBlockFlow {DIV} at (65,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "297.28" + LayoutNGBlockFlow {DIV} at (130,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,3) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 298x16 + LayoutText {#text} at (260,0) size 298x16 + text run at (260,0) width 298: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,268) size 785.55x16 + LayoutNGBlockFlow {DIV} at (0,3) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "14.25" + LayoutNGBlockFlow {DIV} at (65,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "302.59" + LayoutNGBlockFlow {DIV} at (130,3) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,3) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 303x16 + LayoutText {#text} at (260,0) size 303x16 + text run at (260,0) width 303: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,284) size 785.55x17 + LayoutNGBlockFlow {DIV} at (0,4) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "14.50" + LayoutNGBlockFlow {DIV} at (65,4) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "307.91" + LayoutNGBlockFlow {DIV} at (130,4) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,4) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.01" + LayoutInline {SPAN} at (0,0) size 308x17 + LayoutText {#text} at (260,0) size 308x17 + text run at (260,0) width 308: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,301) size 785.55x17 + LayoutNGBlockFlow {DIV} at (0,4) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "14.75" + LayoutNGBlockFlow {DIV} at (65,4) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "313.20" + LayoutNGBlockFlow {DIV} at (130,4) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,4) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 314x17 + LayoutText {#text} at (260,0) size 314x17 + text run at (260,0) width 314: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,318) size 785.55x17 + LayoutNGBlockFlow {DIV} at (0,4) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "15.00" + LayoutNGBlockFlow {DIV} at (65,4) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "318.52" + LayoutNGBlockFlow {DIV} at (130,4) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,4) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 319x17 + LayoutText {#text} at (260,0) size 319x17 + text run at (260,0) width 319: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,335) size 785.55x17 + LayoutNGBlockFlow {DIV} at (0,4) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "15.25" + LayoutNGBlockFlow {DIV} at (65,4) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "323.83" + LayoutNGBlockFlow {DIV} at (130,4) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,4) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 324x17 + LayoutText {#text} at (260,0) size 324x17 + text run at (260,0) width 324: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,352) size 785.55x19 + LayoutNGBlockFlow {DIV} at (0,5) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "15.50" + LayoutNGBlockFlow {DIV} at (65,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "329.14" + LayoutNGBlockFlow {DIV} at (130,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,5) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.01" + LayoutInline {SPAN} at (0,0) size 330x18 + LayoutText {#text} at (260,0) size 330x18 + text run at (260,0) width 330: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,371) size 785.55x19 + LayoutNGBlockFlow {DIV} at (0,5) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "15.75" + LayoutNGBlockFlow {DIV} at (65,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "334.44" + LayoutNGBlockFlow {DIV} at (130,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,5) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 335x18 + LayoutText {#text} at (260,0) size 335x18 + text run at (260,0) width 335: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,390) size 785.55x19 + LayoutNGBlockFlow {DIV} at (0,5) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "16.00" + LayoutNGBlockFlow {DIV} at (65,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "339.75" + LayoutNGBlockFlow {DIV} at (130,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,5) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 340x18 + LayoutText {#text} at (260,0) size 340x18 + text run at (260,0) width 340: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,409) size 785.55x19 + LayoutNGBlockFlow {DIV} at (0,5) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "16.25" + LayoutNGBlockFlow {DIV} at (65,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "345.06" + LayoutNGBlockFlow {DIV} at (130,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,5) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 346x18 + LayoutText {#text} at (260,0) size 346x18 + text run at (260,0) width 346: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,428) size 785.55x20 + LayoutNGBlockFlow {DIV} at (0,5) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "16.50" + LayoutNGBlockFlow {DIV} at (65,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "350.36" + LayoutNGBlockFlow {DIV} at (130,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,5) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.01" + LayoutInline {SPAN} at (0,0) size 351x19 + LayoutText {#text} at (260,0) size 351x19 + text run at (260,0) width 351: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,448) size 785.55x20 + LayoutNGBlockFlow {DIV} at (0,5) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "16.75" + LayoutNGBlockFlow {DIV} at (65,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "355.67" + LayoutNGBlockFlow {DIV} at (130,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,5) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 356x19 + LayoutText {#text} at (260,0) size 356x19 + text run at (260,0) width 356: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,468) size 785.55x20 + LayoutNGBlockFlow {DIV} at (0,5) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "17.00" + LayoutNGBlockFlow {DIV} at (65,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "360.98" + LayoutNGBlockFlow {DIV} at (130,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,5) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 361x19 + LayoutText {#text} at (260,0) size 361x19 + text run at (260,0) width 361: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,488) size 785.55x20 + LayoutNGBlockFlow {DIV} at (0,5) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "17.25" + LayoutNGBlockFlow {DIV} at (65,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "366.30" + LayoutNGBlockFlow {DIV} at (130,5) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,5) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 367x19 + LayoutText {#text} at (260,0) size 367x19 + text run at (260,0) width 367: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,508) size 785.55x22 + LayoutNGBlockFlow {DIV} at (0,7) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "17.50" + LayoutNGBlockFlow {DIV} at (65,7) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "371.59" + LayoutNGBlockFlow {DIV} at (130,7) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,7) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.01" + LayoutInline {SPAN} at (0,0) size 372x21 + LayoutText {#text} at (260,0) size 372x21 + text run at (260,0) width 372: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,530) size 785.55x22 + LayoutNGBlockFlow {DIV} at (0,7) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "17.75" + LayoutNGBlockFlow {DIV} at (65,7) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "376.91" + LayoutNGBlockFlow {DIV} at (130,7) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,7) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 377x21 + LayoutText {#text} at (260,0) size 377x21 + text run at (260,0) width 377: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,552) size 785.55x22 + LayoutNGBlockFlow {DIV} at (0,7) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "18.00" + LayoutNGBlockFlow {DIV} at (65,7) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "382.22" + LayoutNGBlockFlow {DIV} at (130,7) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,7) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 383x21 + LayoutText {#text} at (260,0) size 383x21 + text run at (260,0) width 383: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,574) size 785.55x22 + LayoutNGBlockFlow {DIV} at (0,7) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "18.25" + LayoutNGBlockFlow {DIV} at (65,7) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "387.53" + LayoutNGBlockFlow {DIV} at (130,7) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.82" + LayoutNGBlockFlow {DIV} at (195,7) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 388x21 + LayoutText {#text} at (260,0) size 388x21 + text run at (260,0) width 388: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,596) size 785.55x23 + LayoutNGBlockFlow {DIV} at (0,8) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "18.50" + LayoutNGBlockFlow {DIV} at (65,8) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "392.83" + LayoutNGBlockFlow {DIV} at (130,8) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,8) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.01" + LayoutInline {SPAN} at (0,0) size 393x22 + LayoutText {#text} at (260,0) size 393x22 + text run at (260,0) width 393: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,619) size 785.55x23 + LayoutNGBlockFlow {DIV} at (0,8) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "18.75" + LayoutNGBlockFlow {DIV} at (65,8) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "398.14" + LayoutNGBlockFlow {DIV} at (130,8) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,8) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 399x22 + LayoutText {#text} at (260,0) size 399x22 + text run at (260,0) width 399: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,642) size 785.55x23 + LayoutNGBlockFlow {DIV} at (0,8) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "19.00" + LayoutNGBlockFlow {DIV} at (65,8) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "403.45" + LayoutNGBlockFlow {DIV} at (130,8) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,8) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 404x22 + LayoutText {#text} at (260,0) size 404x22 + text run at (260,0) width 404: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,665) size 785.55x23 + LayoutNGBlockFlow {DIV} at (0,8) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "19.25" + LayoutNGBlockFlow {DIV} at (65,8) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "408.77" + LayoutNGBlockFlow {DIV} at (130,8) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,8) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 409x22 + LayoutText {#text} at (260,0) size 409x22 + text run at (260,0) width 409: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,688) size 785.55x24 + LayoutNGBlockFlow {DIV} at (0,9) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "19.50" + LayoutNGBlockFlow {DIV} at (65,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "414.06" + LayoutNGBlockFlow {DIV} at (130,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,9) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 415x23 + LayoutText {#text} at (260,0) size 415x23 + text run at (260,0) width 415: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,712) size 785.55x24 + LayoutNGBlockFlow {DIV} at (0,9) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "19.75" + LayoutNGBlockFlow {DIV} at (65,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "419.38" + LayoutNGBlockFlow {DIV} at (130,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,9) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 420x23 + LayoutText {#text} at (260,0) size 420x23 + text run at (260,0) width 420: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,736) size 785.55x24 + LayoutNGBlockFlow {DIV} at (0,9) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "20.00" + LayoutNGBlockFlow {DIV} at (65,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "424.69" + LayoutNGBlockFlow {DIV} at (130,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,9) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 425x23 + LayoutText {#text} at (260,0) size 425x23 + text run at (260,0) width 425: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,760) size 785.55x24 + LayoutNGBlockFlow {DIV} at (0,9) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "20.25" + LayoutNGBlockFlow {DIV} at (65,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "430.00" + LayoutNGBlockFlow {DIV} at (130,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,9) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 430x23 + LayoutText {#text} at (260,0) size 430x23 + text run at (260,0) width 430: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,784) size 785.55x25 + LayoutNGBlockFlow {DIV} at (0,9) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "20.50" + LayoutNGBlockFlow {DIV} at (65,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "435.30" + LayoutNGBlockFlow {DIV} at (130,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,9) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 436x24 + LayoutText {#text} at (260,0) size 436x24 + text run at (260,0) width 436: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,809) size 785.55x25 + LayoutNGBlockFlow {DIV} at (0,9) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "20.75" + LayoutNGBlockFlow {DIV} at (65,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "440.61" + LayoutNGBlockFlow {DIV} at (130,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,9) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 441x24 + LayoutText {#text} at (260,0) size 441x24 + text run at (260,0) width 441: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,834) size 785.55x25 + LayoutNGBlockFlow {DIV} at (0,9) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "21.00" + LayoutNGBlockFlow {DIV} at (65,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "445.92" + LayoutNGBlockFlow {DIV} at (130,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,9) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 446x24 + LayoutText {#text} at (260,0) size 446x24 + text run at (260,0) width 446: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,859) size 785.55x25 + LayoutNGBlockFlow {DIV} at (0,9) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "21.25" + LayoutNGBlockFlow {DIV} at (65,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "451.23" + LayoutNGBlockFlow {DIV} at (130,9) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,9) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 452x24 + LayoutText {#text} at (260,0) size 452x24 + text run at (260,0) width 452: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,884) size 785.55x26 + LayoutNGBlockFlow {DIV} at (0,10) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "21.50" + LayoutNGBlockFlow {DIV} at (65,10) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "456.53" + LayoutNGBlockFlow {DIV} at (130,10) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,10) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 457x25 + LayoutText {#text} at (260,0) size 457x25 + text run at (260,0) width 457: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,910) size 785.55x26 + LayoutNGBlockFlow {DIV} at (0,10) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "21.75" + LayoutNGBlockFlow {DIV} at (65,10) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "461.84" + LayoutNGBlockFlow {DIV} at (130,10) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,10) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 462x25 + LayoutText {#text} at (260,0) size 462x25 + text run at (260,0) width 462: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,936) size 785.55x26 + LayoutNGBlockFlow {DIV} at (0,10) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "22.00" + LayoutNGBlockFlow {DIV} at (65,10) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "467.16" + LayoutNGBlockFlow {DIV} at (130,10) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,10) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 468x25 + LayoutText {#text} at (260,0) size 468x25 + text run at (260,0) width 468: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,962) size 785.55x26 + LayoutNGBlockFlow {DIV} at (0,10) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "22.25" + LayoutNGBlockFlow {DIV} at (65,10) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "472.47" + LayoutNGBlockFlow {DIV} at (130,10) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,10) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 473x25 + LayoutText {#text} at (260,0) size 473x25 + text run at (260,0) width 473: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,988) size 785.55x27 + LayoutNGBlockFlow {DIV} at (0,11) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "22.50" + LayoutNGBlockFlow {DIV} at (65,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "477.77" + LayoutNGBlockFlow {DIV} at (130,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,11) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 478x26 + LayoutText {#text} at (260,0) size 478x26 + text run at (260,0) width 478: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1015) size 785.55x27 + LayoutNGBlockFlow {DIV} at (0,11) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "22.75" + LayoutNGBlockFlow {DIV} at (65,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "483.08" + LayoutNGBlockFlow {DIV} at (130,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,11) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 484x26 + LayoutText {#text} at (260,0) size 484x26 + text run at (260,0) width 484: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1042) size 785.55x27 + LayoutNGBlockFlow {DIV} at (0,11) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "23.00" + LayoutNGBlockFlow {DIV} at (65,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "488.39" + LayoutNGBlockFlow {DIV} at (130,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,11) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 489x26 + LayoutText {#text} at (260,0) size 489x26 + text run at (260,0) width 489: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1069) size 785.55x27 + LayoutNGBlockFlow {DIV} at (0,11) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "23.25" + LayoutNGBlockFlow {DIV} at (65,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "493.70" + LayoutNGBlockFlow {DIV} at (130,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,11) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 494x26 + LayoutText {#text} at (260,0) size 494x26 + text run at (260,0) width 494: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1096) size 785.55x28 + LayoutNGBlockFlow {DIV} at (0,11) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "23.50" + LayoutNGBlockFlow {DIV} at (65,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "499.00" + LayoutNGBlockFlow {DIV} at (130,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,11) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 499x27 + LayoutText {#text} at (260,0) size 499x27 + text run at (260,0) width 499: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1124) size 785.55x28 + LayoutNGBlockFlow {DIV} at (0,11) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "23.75" + LayoutNGBlockFlow {DIV} at (65,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "504.31" + LayoutNGBlockFlow {DIV} at (130,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,11) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 505x27 + LayoutText {#text} at (260,0) size 505x27 + text run at (260,0) width 505: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1152) size 785.55x28 + LayoutNGBlockFlow {DIV} at (0,11) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "24.00" + LayoutNGBlockFlow {DIV} at (65,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "509.63" + LayoutNGBlockFlow {DIV} at (130,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,11) size 65x13 + LayoutText {#text} at (40,0) size 20x13 + text run at (40,0) width 20: "0.00" + LayoutInline {SPAN} at (0,0) size 510x27 + LayoutText {#text} at (260,0) size 510x27 + text run at (260,0) width 510: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1180) size 785.55x28 + LayoutNGBlockFlow {DIV} at (0,11) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "24.25" + LayoutNGBlockFlow {DIV} at (65,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "514.92" + LayoutNGBlockFlow {DIV} at (130,11) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,11) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.01" + LayoutInline {SPAN} at (0,0) size 515x27 + LayoutText {#text} at (260,0) size 515x27 + text run at (260,0) width 515: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1208) size 785.55x29 + LayoutNGBlockFlow {DIV} at (0,13) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "24.50" + LayoutNGBlockFlow {DIV} at (65,13) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "520.23" + LayoutNGBlockFlow {DIV} at (130,13) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,13) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 521x28 + LayoutText {#text} at (260,0) size 521x28 + text run at (260,0) width 521: "Amazingly few discotheques provide jukeboxes." + LayoutNGBlockFlow {DIV} at (0,1237) size 785.55x29 + LayoutNGBlockFlow {DIV} at (0,13) size 65x13 + LayoutText {#text} at (34,0) size 26x13 + text run at (34,0) width 26: "24.75" + LayoutNGBlockFlow {DIV} at (65,13) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "525.55" + LayoutNGBlockFlow {DIV} at (130,13) size 65x13 + LayoutText {#text} at (29,0) size 31x13 + text run at (29,0) width 31: "254.81" + LayoutNGBlockFlow {DIV} at (195,13) size 65x13 + LayoutText {#text} at (37,0) size 23x13 + text run at (37,0) width 23: "-0.00" + LayoutInline {SPAN} at (0,0) size 526x28 + LayoutText {#text} at (260,0) size 526x28 + text run at (260,0) width 526: "Amazingly few discotheques provide jukeboxes." + LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-stick-to-bottom-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-stick-to-bottom-expected.txt index d78c87e..72b62a34 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-stick-to-bottom-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-stick-to-bottom-expected.txt
@@ -10,7 +10,7 @@ Running: testEscShouldNotJumpToBottom Is at bottom: false, should stick: false -Running: testChangingPromptTextShouldJumpToBottom +Running: testChangingPromptTextShouldRestickAtBottom Is at bottom: true, should stick: true Running: testViewportMutationsShouldPreserveStickToBottom @@ -21,6 +21,9 @@ New messages were muted: true Refresh was scheduled after dirty state +Running: testShouldNotJumpToBottomWhenMultilinePromptIsBelowMessages +Is at bottom: false, should stick: false + Running: testShouldNotJumpToBottomWhenPromptFillsEntireViewport -Is at bottom: false, should stick: true +Is at bottom: false, should stick: false
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-stick-to-bottom.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-stick-to-bottom.js index ebd8506..49c943910 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-stick-to-bottom.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-viewport-stick-to-bottom.js
@@ -15,6 +15,7 @@ //# sourceURL=console-viewport-stick-to-bottom.js `); + await ConsoleTestRunner.waitUntilConsoleEditorLoaded(); var viewportHeight = 200; ConsoleTestRunner.fixConsoleViewportDimensions(600, viewportHeight); @@ -22,11 +23,13 @@ var viewport = consoleView._viewport; const messagesCount = 150; - logMessagesToConsole(messagesCount, () => TestRunner.runTestSuite(testSuite)); + logMessagesToConsole(messagesCount, async () => { + await ConsoleTestRunner.waitForPendingViewportUpdates(); + TestRunner.runTestSuite(testSuite); + }); var testSuite = [ function testScrollViewportToBottom(next) { - viewport.invalidate(); consoleView._immediatelyScrollToBottom(); dumpAndContinue(next); }, @@ -34,7 +37,8 @@ function testConsoleSticksToBottom(next) { logMessagesToConsole(messagesCount, onMessagesDumped); - function onMessagesDumped() { + async function onMessagesDumped() { + await ConsoleTestRunner.waitForPendingViewportUpdates(); dumpAndContinue(next); } }, @@ -47,8 +51,11 @@ dumpAndContinue(next); }, - function testChangingPromptTextShouldJumpToBottom(next) { + function testChangingPromptTextShouldRestickAtBottom(next) { TestRunner.addSniffer(Console.ConsoleView.prototype, '_promptTextChangedForTest', onContentChanged); + // Since eventSender.keyDown() does not scroll prompt into view, simulate + // behavior by setting a large scrollTop. + consoleView._viewport.element.scrollTop = 1000000; var editorElement = consoleView._prompt.setText('a'); function onContentChanged() { @@ -97,17 +104,22 @@ } }, - function testShouldNotJumpToBottomWhenPromptFillsEntireViewport(next) { - var text = 'Foo'; - for (var i = 0; i < viewportHeight; i++) - text += '\n'; - Console.ConsoleView.clearConsole(); - consoleView._prompt.setText(text); - viewport.element.scrollTop -= 10; + function testShouldNotJumpToBottomWhenMultilinePromptIsBelowMessages(next) { + // Set scrollTop above the bottom. + viewport.element.scrollTop = viewport.element.scrollHeight - viewport.element.clientHeight - 10; + consoleView._prompt.setText('Foo\n\nbar'); - var keyEvent = TestRunner.createKeyEvent('a'); - viewport._contentElement.dispatchEvent(keyEvent); - consoleView._promptElement.dispatchEvent(new Event('input')); + dumpAndContinue(next); + }, + + function testShouldNotJumpToBottomWhenPromptFillsEntireViewport(next) { + consoleView._prompt.setText('Foo' + '\n'.repeat(viewportHeight)); + + // Set scrollTop above the bottom. + viewport.element.scrollTop = viewport.element.scrollHeight - viewport.element.clientHeight - 10; + + // Trigger prompt text change. + consoleView._prompt.setText('Bar' + '\n'.repeat(viewportHeight)); dumpAndContinue(next); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/get-request-blob-data-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/get-request-blob-data-expected.txt new file mode 100644 index 0000000..d93538b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/get-request-blob-data-expected.txt
@@ -0,0 +1,8 @@ +Tests request body blobs support. +[blob] Data included: false, has post data: true +[blob] string1string2 +[orginal] Data included: false, has post data: true +[clone] Data included: false, has post data: true +[orginal] < Cloned request body > +[clone] < Cloned request body > +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/get-request-blob-data.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/get-request-blob-data.js new file mode 100644 index 0000000..f6a9e1d --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/get-request-blob-data.js
@@ -0,0 +1,38 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank(`Tests request body blobs support.`); + + async function reportRequest(label) { + var { params : { request, requestId } } = await dp.Network.onceRequestWillBeSent(); + testRunner.log(`[${label}] Data included: ${request.postData !== undefined}, has post data: ${request.hasPostData}`); + var { result } = await dp.Network.getRequestPostData({ requestId }); + testRunner.log(`[${label}] ${result.postData}`); + } + + async function SendBlobRequest() { + var promise = reportRequest('blob'); + await session.evaluateAsync(` + (function() { + return fetch('/', { method: "POST", body: new Blob(['string1', 'string2']) }); + })(); + `); + await promise; + } + + async function SendClonedRequests() { + var promise = Promise.all([reportRequest('orginal'), reportRequest('clone')]); + await session.evaluateAsync(` + (function() { + var r1 = new Request('/', { method: 'POST', body: '< Cloned request body >' }); + var r2 = r1.clone(); + return Promise.all(fetch(r1), fetch(r2)); + })(); + `); + await promise; + } + + await dp.Network.enable({ maxPostDataSize: 512 }); + await SendBlobRequest(); + await SendClonedRequests(); + + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html b/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html index 3166283..3c360ab 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html
@@ -1,6 +1,6 @@ <!DOCTYPE html> <meta charset=utf-8> -<title>Web Locks API: navigator.locks.acquire method</title> +<title>Web Locks API: navigator.locks.request method</title> <link rel=help href="https://github.com/inexorabletash/web-locks"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -10,22 +10,22 @@ promise_test(async t => { const res = uniqueName(t); - await promise_rejects(t, new TypeError(), navigator.locks.acquire()); - await promise_rejects(t, new TypeError(), navigator.locks.acquire(res)); -}, 'navigator.locks.acquire requires a name and a callback'); + await promise_rejects(t, new TypeError(), navigator.locks.request()); + await promise_rejects(t, new TypeError(), navigator.locks.request(res)); +}, 'navigator.locks.request requires a name and a callback'); promise_test(async t => { const res = uniqueName(t); await promise_rejects( t, new TypeError(), - navigator.locks.acquire(res, {mode: 'foo'}, lock => {})); + navigator.locks.request(res, {mode: 'foo'}, lock => {})); await promise_rejects( t, new TypeError(), - navigator.locks.acquire(res, {mode: null }, lock => {})); - assert_equals(await navigator.locks.acquire( + navigator.locks.request(res, {mode: null }, lock => {})); + assert_equals(await navigator.locks.request( res, {mode: 'exclusive'}, lock => lock.mode), 'exclusive', 'mode is exclusive'); - assert_equals(await navigator.locks.acquire( + assert_equals(await navigator.locks.request( res, {mode: 'shared'}, lock => lock.mode), 'shared', 'mode is shared'); }, 'mode must be "shared" or "exclusive"'); @@ -34,7 +34,7 @@ const res = uniqueName(t); await promise_rejects( t, 'NotSupportedError', - navigator.locks.acquire( + navigator.locks.request( res, {steal: true, ifAvailable: true}, lock => {}), "A NotSupportedError should be thrown if both " + "'steal' and 'ifAvailable' are specified."); @@ -44,7 +44,7 @@ const res = uniqueName(t); await promise_rejects( t, 'NotSupportedError', - navigator.locks.acquire(res, {mode: 'shared', steal: true}, lock => {}), + navigator.locks.request(res, {mode: 'shared', steal: true}, lock => {}), 'Request with mode=shared and steal=true should fail'); }, "The 'steal' option must be used with exclusive locks"); @@ -53,7 +53,7 @@ const controller = new AbortController(); await promise_rejects( t, 'NotSupportedError', - navigator.locks.acquire( + navigator.locks.request( res, {signal: controller.signal, steal: true}, lock => {}), 'Request with signal and steal=true should fail'); }, "The 'signal' and 'steal' options are mutually exclusive"); @@ -63,7 +63,7 @@ const controller = new AbortController(); await promise_rejects( t, 'NotSupportedError', - navigator.locks.acquire( + navigator.locks.request( res, {signal: controller.signal, ifAvailable: true}, lock => {}), 'Request with signal and ifAvailable=true should fail'); }, "The 'signal' and 'ifAvailable' options are mutually exclusive"); @@ -71,19 +71,19 @@ promise_test(async t => { const res = uniqueName(t); await promise_rejects( - t, new TypeError(), navigator.locks.acquire(res, undefined)); + t, new TypeError(), navigator.locks.request(res, undefined)); await promise_rejects( - t, new TypeError(), navigator.locks.acquire(res, null)); + t, new TypeError(), navigator.locks.request(res, null)); await promise_rejects( - t, new TypeError(), navigator.locks.acquire(res, 123)); + t, new TypeError(), navigator.locks.request(res, 123)); await promise_rejects( - t, new TypeError(), navigator.locks.acquire(res, 'abc')); + t, new TypeError(), navigator.locks.request(res, 'abc')); await promise_rejects( - t, new TypeError(), navigator.locks.acquire(res, [])); + t, new TypeError(), navigator.locks.request(res, [])); await promise_rejects( - t, new TypeError(), navigator.locks.acquire(res, {})); + t, new TypeError(), navigator.locks.request(res, {})); await promise_rejects( - t, new TypeError(), navigator.locks.acquire(res, new Promise(r => {}))); + t, new TypeError(), navigator.locks.request(res, new Promise(r => {}))); }, 'callback must be a function'); promise_test(async t => { @@ -91,7 +91,7 @@ let release; const promise = new Promise(r => { release = r; }); - let returned = navigator.locks.acquire(res, lock => { return promise; }); + let returned = navigator.locks.request(res, lock => { return promise; }); const order = []; @@ -104,26 +104,26 @@ assert_array_equals(order, ['holding', 'returned']); -}, 'navigator.locks.acquire\'s returned promise resolves after' + +}, 'navigator.locks.request\'s returned promise resolves after' + ' lock is released'); promise_test(async t => { const res = uniqueName(t); const test_error = {name: 'test'}; - const p = navigator.locks.acquire(res, lock => { + const p = navigator.locks.request(res, lock => { throw test_error; }); - assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise'); + assert_equals(Promise.resolve(p), p, 'request() result is a Promise'); await promise_rejects(t, test_error, p, 'result should reject'); }, 'Returned Promise rejects if callback throws synchronously'); promise_test(async t => { const res = uniqueName(t); const test_error = {name: 'test'}; - const p = navigator.locks.acquire(res, async lock => { + const p = navigator.locks.request(res, async lock => { throw test_error; }); - assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise'); + assert_equals(Promise.resolve(p), p, 'request() result is a Promise'); await promise_rejects(t, test_error, p, 'result should reject'); }, 'Returned Promise rejects if callback throws asynchronously');
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/chromium-waiting-promise-gc.html b/third_party/WebKit/LayoutTests/http/tests/locks/chromium-waiting-promise-gc.html index c6b2335..f5ab42d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/chromium-waiting-promise-gc.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/chromium-waiting-promise-gc.html
@@ -24,7 +24,7 @@ // Acquire the lock, and keep it alive via a promise that never resolves. let resolve, acquired = new Promise(r => { resolve = r; }); - navigator.locks.acquire(res, lock => { + navigator.locks.request(res, lock => { resolve(); // Neither |lock| nor |promise| are retained. @@ -41,9 +41,9 @@ assert_true(observe_lock.wasCollected, 'Lock should be collected'); assert_true(observe_promise.wasCollected, 'Promise should be collected'); - // Now try and acquire the lock. + // Now try and request the lock. let lock = 'should be overwritten'; - await navigator.locks.acquire(res, {ifAvailable: true}, l => { + await navigator.locks.request(res, {ifAvailable: true}, l => { lock = l; }); assert_equals(lock, null, 'Lock acquisition should have failed');
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/frames.html b/third_party/WebKit/LayoutTests/http/tests/locks/frames.html index fd1434e0..366a7ea 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/frames.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/frames.html
@@ -18,7 +18,7 @@ const lock_id = (await postToFrameAndWait( frame, {op: 'request', name: res, mode: 'shared'})).lock_id; - await navigator.locks.acquire(res, {mode: 'shared'}, async lock => { + await navigator.locks.request(res, {mode: 'shared'}, async lock => { await postToFrameAndWait(frame, {op: 'release', lock_id}); }); @@ -36,11 +36,11 @@ // This request should be blocked. let lock_granted = false; - const blocked = navigator.locks.acquire(res, lock => { lock_granted = true; }); + const blocked = navigator.locks.request(res, lock => { lock_granted = true; }); // Verify that we can't get it. let available = undefined; - await navigator.locks.acquire( + await navigator.locks.request( res, {ifAvailable: true}, lock => { available = lock !== null; }); assert_false(available); assert_false(lock_granted); @@ -95,12 +95,12 @@ // This request should be blocked. let lock_granted = false; - const blocked = navigator.locks.acquire( + const blocked = navigator.locks.request( res, lock => { lock_granted = true; }); // Verify that we can't get it. let available = undefined; - await navigator.locks.acquire( + await navigator.locks.request( res, {ifAvailable: true}, lock => { available = lock !== null; }); assert_false(available); assert_false(lock_granted); @@ -123,12 +123,12 @@ // This request should be blocked. let lock_granted = false; - const blocked = navigator.locks.acquire( + const blocked = navigator.locks.request( res, lock => { lock_granted = true; }); // Verify that we can't get it. let available = undefined; - await navigator.locks.acquire( + await navigator.locks.request( res, {ifAvailable: true}, lock => { available = lock !== null; }); assert_false(available); assert_false(lock_granted);
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/held.html b/third_party/WebKit/LayoutTests/http/tests/locks/held.html index 9a1d888..ccf7c0b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/held.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/held.html
@@ -15,8 +15,8 @@ promise_test(async t => { const res = uniqueName(t); - const p = navigator.locks.acquire(res, lock => 123); - assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise'); + const p = navigator.locks.request(res, lock => 123); + assert_equals(Promise.resolve(p), p, 'request() result is a Promise'); assert_equals(await p, 123, 'promise resolves to the returned value'); }, 'callback\'s result is promisified if not async'); @@ -32,7 +32,7 @@ const order = []; - navigator.locks.acquire(res, lock => { + navigator.locks.request(res, lock => { granted(lock); return lock_release_promise; }); @@ -43,7 +43,7 @@ order.push('1st lock released'); resolve(); }), - navigator.locks.acquire(res, () => { + navigator.locks.request(res, () => { order.push('2nd lock granted'); }) ]); @@ -63,7 +63,7 @@ const order = []; - navigator.locks.acquire(res, lock => { + navigator.locks.request(res, lock => { granted(lock); return lock_release_promise; }); @@ -74,7 +74,7 @@ order.push('reject'); reject(new Error('this uncaught rejection is expected')); }), - navigator.locks.acquire(res, () => { + navigator.locks.request(res, () => { order.push('2nd lock granted'); }) ]); @@ -85,8 +85,8 @@ promise_test(async t => { const res = uniqueName(t); let callback_called = false; - await navigator.locks.acquire(res, async lock => { - await navigator.locks.acquire(res, {ifAvailable: true}, lock => { + await navigator.locks.request(res, async lock => { + await navigator.locks.request(res, {ifAvailable: true}, lock => { callback_called = true; assert_equals(lock, null, 'lock request should fail if held'); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/ifAvailable.html b/third_party/WebKit/LayoutTests/http/tests/locks/ifAvailable.html index 7ffe457ba2..36e1f52a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/ifAvailable.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/ifAvailable.html
@@ -9,7 +9,7 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', {ifAvailable: true}, async lock => { + await navigator.locks.request('resource', {ifAvailable: true}, async lock => { callback_called = true; assert_not_equals(lock, null, 'lock should be granted'); }); @@ -18,9 +18,9 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', async lock => { + await navigator.locks.request('resource', async lock => { // Request would time out if |ifAvailable| was not specified. - const result = await navigator.locks.acquire( + const result = await navigator.locks.request( 'resource', {ifAvailable: true}, async lock => { callback_called = true; assert_equals(lock, null, 'lock should not be granted'); @@ -33,10 +33,10 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', async lock => { + await navigator.locks.request('resource', async lock => { try { // Request would time out if |ifAvailable| was not specified. - await navigator.locks.acquire('resource', {ifAvailable: true}, async lock => { + await navigator.locks.request('resource', {ifAvailable: true}, async lock => { callback_called = true; assert_equals(lock, null, 'lock should not be granted'); throw 123; @@ -51,9 +51,9 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', async lock => { + await navigator.locks.request('resource', async lock => { // Request with a different name - should be grantable. - await navigator.locks.acquire('different', {ifAvailable: true}, async lock => { + await navigator.locks.request('different', {ifAvailable: true}, async lock => { callback_called = true; assert_not_equals(lock, null, 'lock should be granted'); }); @@ -63,8 +63,8 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', {mode: 'shared'}, async lock => { - await navigator.locks.acquire( + await navigator.locks.request('resource', {mode: 'shared'}, async lock => { + await navigator.locks.request( 'resource', {mode: 'shared', ifAvailable: true}, async lock => { callback_called = true; assert_not_equals(lock, null, 'lock should be granted'); @@ -75,9 +75,9 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', {mode: 'shared'}, async lock => { + await navigator.locks.request('resource', {mode: 'shared'}, async lock => { // Request would time out if |ifAvailable| was not specified. - await navigator.locks.acquire('resource', {ifAvailable: true}, async lock => { + await navigator.locks.request('resource', {ifAvailable: true}, async lock => { callback_called = true; assert_equals(lock, null, 'lock should not be granted'); }); @@ -87,9 +87,9 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', async lock => { + await navigator.locks.request('resource', async lock => { // Request would time out if |ifAvailable| was not specified. - await navigator.locks.acquire( + await navigator.locks.request( 'resource', {mode: 'shared', ifAvailable: true}, async lock => { callback_called = true; assert_equals(lock, null, 'lock should not be granted'); @@ -100,15 +100,15 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', async lock => { + await navigator.locks.request('resource', async lock => { callback_called = true; const test_error = {name: 'test'}; - const p = navigator.locks.acquire( + const p = navigator.locks.request( 'resource', {ifAvailable: true}, lock => { assert_equals(lock, null, 'lock should not be available'); throw test_error; }); - assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise'); + assert_equals(Promise.resolve(p), p, 'request() result is a Promise'); await promise_rejects(t, test_error, p, 'result should reject'); }); assert_true(callback_called, 'callback should be called'); @@ -116,15 +116,15 @@ promise_test(async t => { let callback_called = false; - await navigator.locks.acquire('resource', async lock => { + await navigator.locks.request('resource', async lock => { callback_called = true; const test_error = {name: 'test'}; - const p = navigator.locks.acquire( + const p = navigator.locks.request( 'resource', {ifAvailable: true}, async lock => { assert_equals(lock, null, 'lock should not be available'); throw test_error; }); - assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise'); + assert_equals(Promise.resolve(p), p, 'request() result is a Promise'); await promise_rejects(t, test_error, p, 'result should reject'); }); assert_true(callback_called, 'callback should be called');
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.html b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.html index c98fcde..dfd03b6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.html
@@ -28,7 +28,7 @@ idl_array.add_idls(idls); let lock; - await navigator.locks.acquire('name', l => { lock = l; }); + await navigator.locks.request('name', l => { lock = l; }); idl_array.add_objects({ LockManager: [navigator.locks],
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.idl b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.idl index b1897ef..7c7d7c3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.idl +++ b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.idl
@@ -20,9 +20,9 @@ [Exposed=(Window,Worker), SecureContext] interface LockManager { - Promise<any> acquire(DOMString name, + Promise<any> request(DOMString name, LockGrantedCallback callback); - Promise<any> acquire(DOMString name, + Promise<any> request(DOMString name, LockOptions options, LockGrantedCallback callback);
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/lock-attributes.html b/third_party/WebKit/LayoutTests/http/tests/locks/lock-attributes.html index 39970ea..e0c1c5b3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/lock-attributes.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/lock-attributes.html
@@ -8,14 +8,14 @@ 'use strict'; promise_test(async t => { - await navigator.locks.acquire('resource', lock => { + await navigator.locks.request('resource', lock => { assert_equals(lock.name, 'resource'); assert_equals(lock.mode, 'exclusive'); }); }, 'Lock attributes reflect requested properties (exclusive)'); promise_test(async t => { - await navigator.locks.acquire('resource', {mode: 'shared'}, lock => { + await navigator.locks.request('resource', {mode: 'shared'}, lock => { assert_equals(lock.name, 'resource'); assert_equals(lock.mode, 'shared'); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/mode-exclusive.html b/third_party/WebKit/LayoutTests/http/tests/locks/mode-exclusive.html index 52507b6..7769ca5e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/mode-exclusive.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/mode-exclusive.html
@@ -12,9 +12,9 @@ function log_grant(n) { return () => { granted.push(n); }; } await Promise.all([ - navigator.locks.acquire('a', log_grant(1)), - navigator.locks.acquire('a', log_grant(2)), - navigator.locks.acquire('a', log_grant(3)) + navigator.locks.request('a', log_grant(1)), + navigator.locks.request('a', log_grant(2)), + navigator.locks.request('a', log_grant(3)) ]); assert_array_equals(granted, [1, 2, 3]); }, 'Lock requests are granted in order'); @@ -24,12 +24,12 @@ function log_grant(n) { return () => { granted.push(n); }; } let inner_promise; - await navigator.locks.acquire('a', async lock => { + await navigator.locks.request('a', async lock => { inner_promise = Promise.all([ // This will be blocked. - navigator.locks.acquire('a', log_grant(1)), + navigator.locks.request('a', log_grant(1)), // But this should be grantable immediately. - navigator.locks.acquire('b', log_grant(2)) + navigator.locks.request('b', log_grant(2)) ]); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/mode-mixed.html b/third_party/WebKit/LayoutTests/http/tests/locks/mode-mixed.html index f18dae8..ac8f365 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/mode-mixed.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/mode-mixed.html
@@ -14,22 +14,22 @@ const granted = []; // These should be granted immediately, and held until unblocked. - navigator.locks.acquire('a', {mode: 'shared'}, async lock => { + navigator.locks.request('a', {mode: 'shared'}, async lock => { granted.push('a-shared-1'); await blocked; }); - navigator.locks.acquire('a', {mode: 'shared'}, async lock => { + navigator.locks.request('a', {mode: 'shared'}, async lock => { granted.push('a-shared-2'); await blocked; }); - navigator.locks.acquire('a', {mode: 'shared'}, async lock => { + navigator.locks.request('a', {mode: 'shared'}, async lock => { granted.push('a-shared-3'); await blocked; }); // This should be blocked. let exclusive_lock; - const exclusive_request = navigator.locks.acquire('a', async lock => { + const exclusive_request = navigator.locks.request('a', async lock => { granted.push('a-exclusive'); exclusive_lock = lock; }); // This should be granted immediately (different name). - await navigator.locks.acquire('b', {mode: 'exclusive'}, lock => { + await navigator.locks.request('b', {mode: 'exclusive'}, lock => { granted.push('b-exclusive'); }); assert_array_equals(
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/mode-shared.html b/third_party/WebKit/LayoutTests/http/tests/locks/mode-shared.html index 6c1f92c..cac3a57 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/mode-shared.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/mode-shared.html
@@ -12,12 +12,12 @@ function log_grant(n) { return () => { granted.push(n); }; } await Promise.all([ - navigator.locks.acquire('a', {mode: 'shared'}, log_grant(1)), - navigator.locks.acquire('b', {mode: 'shared'}, log_grant(2)), - navigator.locks.acquire('c', {mode: 'shared'}, log_grant(3)), - navigator.locks.acquire('a', {mode: 'shared'}, log_grant(4)), - navigator.locks.acquire('b', {mode: 'shared'}, log_grant(5)), - navigator.locks.acquire('c', {mode: 'shared'}, log_grant(6)), + navigator.locks.request('a', {mode: 'shared'}, log_grant(1)), + navigator.locks.request('b', {mode: 'shared'}, log_grant(2)), + navigator.locks.request('c', {mode: 'shared'}, log_grant(3)), + navigator.locks.request('a', {mode: 'shared'}, log_grant(4)), + navigator.locks.request('b', {mode: 'shared'}, log_grant(5)), + navigator.locks.request('c', {mode: 'shared'}, log_grant(6)), ]); assert_array_equals(granted, [1, 2, 3, 4, 5, 6]); @@ -26,13 +26,13 @@ promise_test(async t => { let a_acquired = false, a_acquired_again = false; - await navigator.locks.acquire('a', {mode: 'shared'}, async lock => { + await navigator.locks.request('a', {mode: 'shared'}, async lock => { a_acquired = true; // Since lock is held, this request would be blocked if the // lock was not 'shared', causing this test to time out. - await navigator.locks.acquire('a', {mode: 'shared'}, lock => { + await navigator.locks.request('a', {mode: 'shared'}, lock => { a_acquired_again = true; }); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/opaque-origin.html b/third_party/WebKit/LayoutTests/http/tests/locks/opaque-origin.html index 724dd0f2..7abae82 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/opaque-origin.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/opaque-origin.html
@@ -34,7 +34,7 @@ "use strict"; window.onmessage = async () => { try { - await navigator.locks.acquire('name', lock => {}); + await navigator.locks.request('name', lock => {}); window.parent.postMessage({result: "no exception"}, "*"); } catch (ex) { window.parent.postMessage({result: ex.name}, "*"); @@ -48,8 +48,8 @@ iframe.contentWindow.postMessage({}, '*'); const message = await wait_for_message(iframe); assert_equals(message.result, 'no exception', - 'navigator.locks.acquire() should not throw'); -}, 'navigator.locks.acquire() in non-sandboxed iframe should not throw'); + 'navigator.locks.request() should not throw'); +}, 'navigator.locks.request() in non-sandboxed iframe should not throw'); promise_test(async t => { const iframe = await load_iframe(script, 'allow-scripts'); @@ -57,5 +57,5 @@ const message = await wait_for_message(iframe); assert_equals(message.result, 'SecurityError', 'Exception should be SecurityError'); -}, 'navigator.locks.acquire() in sandboxed iframe should throw SecurityError'); +}, 'navigator.locks.request() in sandboxed iframe should throw SecurityError'); </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/query-order.html b/third_party/WebKit/LayoutTests/http/tests/locks/query-order.html index 0fc358c..25ac10a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/query-order.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/query-order.html
@@ -14,7 +14,7 @@ let release; const promise = new Promise(resolve => { release = resolve; }); return new Promise(resolve => { - navigator.locks.acquire(name, options || {}, lock => { + navigator.locks.request(name, options || {}, lock => { resolve(release); return promise; }).catch(_ => {}); @@ -34,9 +34,9 @@ ]); // These requests should be blocked. - navigator.locks.acquire(res3, {mode: 'shared'}, lock => {}); - navigator.locks.acquire(res2, {mode: 'shared'}, lock => {}); - navigator.locks.acquire(res1, {mode: 'shared'}, lock => {}); + navigator.locks.request(res3, {mode: 'shared'}, lock => {}); + navigator.locks.request(res2, {mode: 'shared'}, lock => {}); + navigator.locks.request(res1, {mode: 'shared'}, lock => {}); const state = await navigator.locks.query(); @@ -68,7 +68,7 @@ // Ensure the requests have had a chance to get queued by // waiting for something else to make it through the queue. - await navigator.locks.acquire(uniqueName(t), lock => {}); + await navigator.locks.request(uniqueName(t), lock => {}); // Now release the previous holders. release2();
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/query.html b/third_party/WebKit/LayoutTests/http/tests/locks/query.html index 76275ac6..77d37f3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/query.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/query.html
@@ -20,13 +20,13 @@ promise_test(async t => { const res = uniqueName(t); - await navigator.locks.acquire(res, async lock1 => { - // Attempt to acquire this again - should be blocked. + await navigator.locks.request(res, async lock1 => { + // Attempt to request this again - should be blocked. let lock2_acquired = false; - navigator.locks.acquire(res, lock2 => { lock2_acquired = true; }); + navigator.locks.request(res, lock2 => { lock2_acquired = true; }); // Verify that it was blocked. - await navigator.locks.acquire(res, {ifAvailable: true}, async lock3 => { + await navigator.locks.request(res, {ifAvailable: true}, async lock3 => { assert_false(lock2_acquired, 'second request should be blocked'); assert_equals(lock3, null, 'third request should have failed'); @@ -62,13 +62,13 @@ promise_test(async t => { const res = uniqueName(t); - await navigator.locks.acquire(res, async lock1 => { + await navigator.locks.request(res, async lock1 => { const state = await navigator.locks.query(); assert_array_equals(modes(state.held, res), ['exclusive'], 'Held lock should appear once'); }); - await navigator.locks.acquire(res, {mode: 'shared'}, async lock1 => { + await navigator.locks.request(res, {mode: 'shared'}, async lock1 => { const state = await navigator.locks.query(); assert_array_equals(modes(state.held, res), ['shared'], 'Held lock should appear once'); @@ -79,8 +79,8 @@ const res1 = uniqueName(t); const res2 = uniqueName(t); - await navigator.locks.acquire(res1, async lock1 => { - await navigator.locks.acquire(res2, {mode: 'shared'}, async lock2 => { + await navigator.locks.request(res1, async lock1 => { + await navigator.locks.request(res2, {mode: 'shared'}, async lock2 => { const state = await navigator.locks.query(); assert_array_equals(modes(state.held, res1), ['exclusive'], 'Held lock should appear once'); @@ -93,13 +93,13 @@ promise_test(async t => { const res = uniqueName(t); - await navigator.locks.acquire(res, async lock1 => { - // Attempt to acquire this again - should be blocked. + await navigator.locks.request(res, async lock1 => { + // Attempt to request this again - should be blocked. let lock2_acquired = false; - navigator.locks.acquire(res, lock2 => { lock2_acquired = true; }); + navigator.locks.request(res, lock2 => { lock2_acquired = true; }); // Verify that it was blocked. - await navigator.locks.acquire(res, {ifAvailable: true}, async lock3 => { + await navigator.locks.request(res, {ifAvailable: true}, async lock3 => { assert_false(lock2_acquired, 'second request should be blocked'); assert_equals(lock3, null, 'third request should have failed'); @@ -115,8 +115,8 @@ promise_test(async t => { const res = uniqueName(t); - await navigator.locks.acquire(res, {mode: 'shared'}, async lock1 => { - await navigator.locks.acquire(res, {mode: 'shared'}, async lock2 => { + await navigator.locks.request(res, {mode: 'shared'}, async lock1 => { + await navigator.locks.request(res, {mode: 'shared'}, async lock2 => { const state = await navigator.locks.query(); assert_array_equals(modes(state.held, res), ['shared', 'shared'], 'Held lock should appear twice'); @@ -127,14 +127,14 @@ promise_test(async t => { const res = uniqueName(t); - await navigator.locks.acquire(res, async lock1 => { + await navigator.locks.request(res, async lock1 => { let lock2_acquired = false, lock3_acquired = false; - navigator.locks.acquire(res, {mode: 'shared'}, + navigator.locks.request(res, {mode: 'shared'}, lock2 => { lock2_acquired = true; }); - navigator.locks.acquire(res, {mode: 'shared'}, + navigator.locks.request(res, {mode: 'shared'}, lock3 => { lock3_acquired = true; }); - await navigator.locks.acquire(res, {ifAvailable: true}, async lock4 => { + await navigator.locks.request(res, {ifAvailable: true}, async lock4 => { assert_equals(lock4, null, 'lock should not be available'); assert_false(lock2_acquired, 'second attempt should be blocked'); assert_false(lock3_acquired, 'third attempt should be blocked'); @@ -153,8 +153,8 @@ const res1 = uniqueName(t); const res2 = uniqueName(t); - await navigator.locks.acquire(res1, async lock1 => { - await navigator.locks.acquire(res2, async lock2 => { + await navigator.locks.request(res1, async lock1 => { + await navigator.locks.request(res2, async lock2 => { const state = await navigator.locks.query(); const res1_clients = clients(state.held, res1); @@ -178,7 +178,7 @@ await postToWorkerAndWait( worker, {op: 'request', name: res, mode: 'shared'}); - await navigator.locks.acquire(res, {mode: 'shared'}, async lock => { + await navigator.locks.request(res, {mode: 'shared'}, async lock => { const state = await navigator.locks.query(); const res_clients = clients(state.held, res); assert_equals(res_clients.length, 2, 'Clients should have same resource'); @@ -199,7 +199,7 @@ // Acquire 2 here. await new Promise(resolve => { - navigator.locks.acquire(res2, lock => { + navigator.locks.request(res2, lock => { resolve(); return new Promise(() => {}); // Never released. }); @@ -212,7 +212,7 @@ })).failed, 'Lock request should have failed'); // Request 1 here. - navigator.locks.acquire( + navigator.locks.request( res1, t.unreached_func('Lock should not be acquired')); // Verify that we're seeing a deadlock.
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/resource-names.html b/third_party/WebKit/LayoutTests/http/tests/locks/resource-names.html index 118cec8..1dfe11d5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/resource-names.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/resource-names.html
@@ -22,7 +22,7 @@ '\uFFFF' // Non-character ].forEach(string => { promise_test(async t => { - await navigator.locks.acquire(string, lock => { + await navigator.locks.request(string, lock => { assert_equals(lock.name, string, 'Requested name matches granted name'); }); @@ -31,13 +31,13 @@ promise_test(async t => { // '\uD800' treated as a USVString would become '\uFFFD'. - await navigator.locks.acquire('\uD800', async lock => { + await navigator.locks.request('\uD800', async lock => { assert_equals(lock.name, '\uD800'); // |lock| is held for the duration of this name. It // Should not block acquiring |lock2| with a distinct // DOMString. - await navigator.locks.acquire('\uFFFD', lock2 => { + await navigator.locks.request('\uFFFD', lock2 => { assert_equals(lock2.name, '\uFFFD'); }); @@ -49,11 +49,11 @@ for (const name of ['-', '-foo']) { await promise_rejects( t, 'NotSupportedError', - navigator.locks.acquire(name, lock => {}), + navigator.locks.request(name, lock => {}), 'Names starting with "-" should be rejected'); } let got_lock = false; - await navigator.locks.acquire('x-anything', lock => { + await navigator.locks.request('x-anything', lock => { got_lock = true; }); assert_true(got_lock, 'Names with embedded "-" should be accepted');
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/resources/iframe.html b/third_party/WebKit/LayoutTests/http/tests/locks/resources/iframe.html index 9998c341..d3799f4 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/resources/iframe.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/resources/iframe.html
@@ -15,7 +15,7 @@ switch (e.data.op) { case 'request': - navigator.locks.acquire( + navigator.locks.request( e.data.name, { mode: e.data.mode || 'exclusive', ifAvailable: e.data.ifAvailable || false
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/resources/interfaces-worker.js b/third_party/WebKit/LayoutTests/http/tests/locks/resources/interfaces-worker.js index 186d971..0a099861 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/resources/interfaces-worker.js +++ b/third_party/WebKit/LayoutTests/http/tests/locks/resources/interfaces-worker.js
@@ -16,7 +16,7 @@ idl_array.add_idls(idls); let lock; - await navigator.locks.acquire('name', l => { lock = l; }); + await navigator.locks.request('name', l => { lock = l; }); idl_array.add_objects({ LockManager: [navigator.locks],
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/resources/worker.js b/third_party/WebKit/LayoutTests/http/tests/locks/resources/worker.js index 56bc533..9bb5d3d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/resources/worker.js +++ b/third_party/WebKit/LayoutTests/http/tests/locks/resources/worker.js
@@ -12,7 +12,7 @@ switch (e.data.op) { case 'request': - navigator.locks.acquire( + navigator.locks.request( e.data.name, { mode: e.data.mode || 'exclusive', ifAvailable: e.data.ifAvailable || false
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/signal.html b/third_party/WebKit/LayoutTests/http/tests/locks/signal.html index fe49ee5..e18c49a1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/signal.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/signal.html
@@ -15,7 +15,7 @@ for (const signal of ['string', 12.34, false, {}, Symbol(), () => {}, self]) { await promise_rejects( t, new TypeError(), - navigator.locks.acquire( + navigator.locks.request( res, {signal}, t.unreached_func('callback should not run')), 'Bindings should throw if the signal option is a not an AbortSignal'); } @@ -24,7 +24,7 @@ for (const signal of [null, undefined]) { assert_equals( undefined, - await navigator.locks.acquire(res, {signal}, lock => {}), + await navigator.locks.request(res, {signal}, lock => {}), 'Bindings should accept a null-ish signal option'); } }, 'The signal option must be an AbortSignal'); @@ -36,7 +36,7 @@ await promise_rejects( t, 'AbortError', - navigator.locks.acquire(res, {signal: controller.signal}, + navigator.locks.request(res, {signal: controller.signal}, t.unreached_func('callback should not run')), 'Request should reject with AbortError'); }, 'Passing an already aborted signal aborts'); @@ -46,12 +46,12 @@ // Grab a lock and hold it forever. const never_settled = new Promise(resolve => { /* never */ }); - navigator.locks.acquire(res, lock => never_settled); + navigator.locks.request(res, lock => never_settled); const controller = new AbortController(); const promise = - navigator.locks.acquire(res, {signal: controller.signal}, + navigator.locks.request(res, {signal: controller.signal}, t.unreached_func('callback should not run')); // Verify the request is enqueued: @@ -73,12 +73,12 @@ // Grab a lock and hold it forever. const never_settled = new Promise(resolve => { /* never */ }); - navigator.locks.acquire(res, lock => never_settled); + navigator.locks.request(res, lock => never_settled); const controller = new AbortController(); const promise = - navigator.locks.acquire(res, {signal: controller.signal}, lock => {}); + navigator.locks.request(res, {signal: controller.signal}, lock => {}); // Verify the request is enqueued: const state = await navigator.locks.query(); @@ -105,7 +105,7 @@ const controller = new AbortController(); let got_lock = false; - await navigator.locks.acquire( + await navigator.locks.request( res, {signal: controller.signal}, async lock => { got_lock = true; }); assert_true(got_lock, 'Lock should be acquired if abort is not signaled.'); @@ -118,7 +118,7 @@ const controller = new AbortController(); let got_lock = false; - const p = navigator.locks.acquire( + const p = navigator.locks.request( res, {signal: controller.signal}, lock => { got_lock = true; }); // Even though lock is grantable, this abort should be processed synchronously. @@ -128,7 +128,7 @@ assert_false(got_lock, 'Request should be aborted if signal is synchronous'); - await navigator.locks.acquire(res, lock => { got_lock = true; }); + await navigator.locks.request(res, lock => { got_lock = true; }); assert_true(got_lock, 'Subsequent request should not be blocked'); }, 'Synchronously signaled abort'); @@ -139,10 +139,10 @@ const controller = new AbortController(); let got_lock = false; - await navigator.locks.acquire(res, async lock => { + await navigator.locks.request(res, async lock => { got_lock = true; // Now that we have the lock, aborting the request should be ignored, - // and the acquire() call should not reject. + // and the request() call should not reject. controller.abort(); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/steal.html b/third_party/WebKit/LayoutTests/http/tests/locks/steal.html index f53034c..b796c24 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/steal.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/steal.html
@@ -13,7 +13,7 @@ promise_test(async t => { const res = uniqueName(t); let callback_called = false; - await navigator.locks.acquire(res, {steal: true}, lock => { + await navigator.locks.request(res, {steal: true}, lock => { callback_called = true; assert_not_equals(lock, null, 'Lock should be granted'); }); @@ -25,10 +25,10 @@ let callback_called = false; // Grab and hold the lock. - navigator.locks.acquire(res, lock => never_settled).catch(_ => {}); + navigator.locks.request(res, lock => never_settled).catch(_ => {}); // Steal it. - await navigator.locks.acquire(res, {steal: true}, lock => { + await navigator.locks.request(res, {steal: true}, lock => { callback_called = true; assert_not_equals(lock, null, 'Lock should be granted'); }); @@ -40,12 +40,12 @@ const res = uniqueName(t); // Grab and hold the lock. - const promise = navigator.locks.acquire(res, lock => never_settled); + const promise = navigator.locks.request(res, lock => never_settled); const assertion = promise_rejects( t, 'AbortError', promise, `Initial request's promise should reject`); // Steal it. - await navigator.locks.acquire(res, {steal: true}, lock => {}); + await navigator.locks.request(res, {steal: true}, lock => {}); await assertion; @@ -55,16 +55,16 @@ const res = uniqueName(t); // Grab and hold the lock. - navigator.locks.acquire(res, lock => never_settled).catch(_ => {}); + navigator.locks.request(res, lock => never_settled).catch(_ => {}); // Make a request for it. let request_granted = false; - const promise = navigator.locks.acquire(res, lock => { + const promise = navigator.locks.request(res, lock => { request_granted = true; }); // Steal it. - await navigator.locks.acquire(res, {steal: true}, lock => { + await navigator.locks.request(res, {steal: true}, lock => { assert_false(request_granted, 'Steal should override request'); }); @@ -77,17 +77,17 @@ const res = uniqueName(t); // Grab and hold the lock. - navigator.locks.acquire(res, lock => never_settled).catch(_ => {}); + navigator.locks.request(res, lock => never_settled).catch(_ => {}); // Steal it. let saw_abort = false; - const first_steal = navigator.locks.acquire( + const first_steal = navigator.locks.request( res, {steal: true}, lock => never_settled).catch(error => { saw_abort = true; }); // Steal it again. - await navigator.locks.acquire(res, {steal: true}, lock => {}); + await navigator.locks.request(res, {steal: true}, lock => {}); await first_steal; assert_true(saw_abort, 'First steal should have aborted');
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/workers.html b/third_party/WebKit/LayoutTests/http/tests/locks/workers.html index fe6d4b9..1e69919 100644 --- a/third_party/WebKit/LayoutTests/http/tests/locks/workers.html +++ b/third_party/WebKit/LayoutTests/http/tests/locks/workers.html
@@ -17,7 +17,7 @@ const lock_id = (await postToWorkerAndWait( worker, {op: 'request', name: res, mode: 'shared'})).lock_id; - await navigator.locks.acquire(res, {mode: 'shared'}, async lock => { + await navigator.locks.request(res, {mode: 'shared'}, async lock => { await postToWorkerAndWait(worker, {op: 'release', lock_id}); }); @@ -35,12 +35,12 @@ // This request should be blocked. let lock_granted = false; - const blocked = navigator.locks.acquire( + const blocked = navigator.locks.request( res, lock => { lock_granted = true; }); // Verify we can't get it. let available = undefined; - await navigator.locks.acquire( + await navigator.locks.request( res, {ifAvailable: true}, lock => { available = lock !== null; }); assert_false(available); assert_false(lock_granted); @@ -96,12 +96,12 @@ // This request should be blocked. let lock_granted = false; - const blocked = navigator.locks.acquire( + const blocked = navigator.locks.request( res, lock => { lock_granted = true; }); // Verify we can't get it. let available = undefined; - await navigator.locks.acquire( + await navigator.locks.request( res, {ifAvailable: true}, lock => { available = lock !== null; }); assert_false(available); assert_false(lock_granted);
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index d560099..27023a1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -720,9 +720,9 @@ method constructor interface LockManager attribute @@toStringTag - method acquire method constructor method query + method request interface MessageChannel attribute @@toStringTag getter port1
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/scriptParsedHash-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/scriptParsedHash-expected.txt deleted file mode 100644 index abc78e2..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/scriptParsedHash-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -Tests hash field in scriptParsed event. -Hash received: 1C6D2E82E4E4F1BA4CB5762843D429DC872EBA18 -Hash received: EBF1ECD351E7A3294CB5762843D429DC872EBA18 -Hash received: 22D0043331237371241FC675A984B967025A3DC0 -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/scriptParsedHash.js b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/scriptParsedHash.js deleted file mode 100644 index 5d425b6..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/scriptParsedHash.js +++ /dev/null
@@ -1,24 +0,0 @@ -(async function(testRunner) { - var {page, session, dp} = await testRunner.startBlank('Tests hash field in scriptParsed event.'); - - var hashes = new Set(['1C6D2E82E4E4F1BA4CB5762843D429DC872EBA18', - 'EBF1ECD351E7A3294CB5762843D429DC872EBA18', - '22D0043331237371241FC675A984B967025A3DC0']); - - dp.Debugger.enable(); - dp.Debugger.onScriptParsed(messageObject => { - if (hashes.has(messageObject.params.hash)) - testRunner.log('Hash received: ' + messageObject.params.hash); - }); - - function longScript() { - var longScript = "var b = 1;"; - for (var i = 0; i < 2024; ++i) - longScript += "++b;"; - } - - dp.Runtime.evaluate({expression: '1'}); - dp.Runtime.evaluate({expression: '239'}); - await dp.Runtime.evaluate({expression: '(' + longScript + ')()' }); - testRunner.completeTest(); -})
diff --git a/third_party/WebKit/LayoutTests/media/autoplay/console-warning-gesture-media-expected.txt b/third_party/WebKit/LayoutTests/media/autoplay/console-warning-gesture-media-expected.txt new file mode 100644 index 0000000..a2ca2b9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/autoplay/console-warning-gesture-media-expected.txt
@@ -0,0 +1,2 @@ +CONSOLE WARNING: line 2: <iframe gesture="media"> is not supported. Use <iframe allow="autoplay">, https://goo.gl/ximf56 +
diff --git a/third_party/WebKit/LayoutTests/media/autoplay/console-warning-gesture-media.html b/third_party/WebKit/LayoutTests/media/autoplay/console-warning-gesture-media.html new file mode 100644 index 0000000..b06cf33 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/autoplay/console-warning-gesture-media.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<iframe gesture=media></iframe> +<script> +if (window.testRunner) + testRunner.dumpAsText() +</script>
diff --git a/third_party/WebKit/LayoutTests/paint/filters/absolute-under-clip-under-filter-expected.html b/third_party/WebKit/LayoutTests/paint/filters/absolute-under-clip-under-filter-expected.html new file mode 100644 index 0000000..ae3e008 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/filters/absolute-under-clip-under-filter-expected.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +Passes if there is a blurred rectangle, left half blue and right half green. +<div style="filter: blur(10px)"> + <div style="width: 100px; height: 100px; background: blue"> + <div style="position: relative; left: 50px; width: 50px; height: 100px; background: green"></div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/paint/filters/absolute-under-clip-under-filter.html b/third_party/WebKit/LayoutTests/paint/filters/absolute-under-clip-under-filter.html new file mode 100644 index 0000000..bb3380cf --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/filters/absolute-under-clip-under-filter.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +Passes if there is a blurred rectangle, left half blue and right half green. +<div style="filter: blur(10px)"> + <div style="position: relative; width: 100px; height: 100px; background: blue; overflow: hidden"> + <div style="position: absolute; width: 100px; height: 100px; right: -50px; background: green"></div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/filters/filter-on-html-element-with-fixed-position-child-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/filters/filter-on-html-element-with-fixed-position-child-expected.txt index f0b3f50..6886418 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/filters/filter-on-html-element-with-fixed-position-child-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/filters/filter-on-html-element-with-fixed-position-child-expected.txt
@@ -8,7 +8,7 @@ { "object": "LayoutView #document", "rect": [0, 0, 800, 600], - "reason": "subtree" + "reason": "full" } ] }, @@ -24,39 +24,24 @@ "backgroundColor": "#FFFFFF", "paintInvalidations": [ { - "object": "LayoutBlockFlow HTML", - "rect": [0, 0, 785, 10016], - "reason": "subtree" - }, - { - "object": "LayoutBlockFlow BODY", - "rect": [8, 8, 769, 10000], - "reason": "subtree" - }, - { - "object": "LayoutBlockFlow DIV", - "rect": [8, 8, 200, 10000], - "reason": "subtree" - }, - { "object": "LayoutBlockFlow (positioned) DIV", "rect": [100, 110, 100, 100], - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow (positioned) DIV", "rect": [100, 100, 100, 100], - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow (positioned) DIV", "rect": [8, 18, 100, 100], - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow (positioned) DIV", "rect": [8, 8, 100, 100], - "reason": "subtree" + "reason": "geometry" } ], "transform": 1 @@ -77,27 +62,27 @@ "objectPaintInvalidations": [ { "object": "LayoutView #document", - "reason": "subtree" + "reason": "full" }, { "object": "LayoutBlockFlow HTML", - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow BODY", - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow (positioned) DIV", - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow (positioned) DIV", - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow DIV", - "reason": "subtree" + "reason": "geometry" } ] }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt index 2a41afa1..b4f4e4e 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/scroll/scrolled-iframe-scrollbar-change-expected.txt
@@ -13,10 +13,6 @@ "reason": "geometry" }, { - "object": "LayoutView #document", - "reason": "style change" - }, - { "object": "LayoutBlockFlow BODY class='noScroll'", "reason": "style change" },
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/reflections/nested-reflection-on-overflow-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/compositing/reflections/nested-reflection-on-overflow-expected.txt index 4f2cdbe..92c1af3 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/compositing/reflections/nested-reflection-on-overflow-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/reflections/nested-reflection-on-overflow-expected.txt
@@ -12,7 +12,7 @@ LayoutBlockFlow {DIV} at (11,11) size 100x100 [bgcolor=#008000] layer at (39,67) size 100x100 clip at (39,67) size 85x85 scrollHeight 500 LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 100x100 -layer at (39,67) size 85x500 backgroundClip at (39,67) size 232x210 clip at (39,67) size 232x210 +layer at (39,67) size 85x500 backgroundClip at (39,67) size 85x85 clip at (39,67) size 85x85 LayoutBlockFlow {DIV} at (0,0) size 85x500 LayoutText {#text} at (0,0) size 84x459 text run at (0,0) width 84: "Lorem ipsum"
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/reflection/reflection-with-rotation-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/reflection/reflection-with-rotation-expected.txt index 0cd1aa88..a1bb279 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/reflection/reflection-with-rotation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/reflection/reflection-with-rotation-expected.txt
@@ -3,6 +3,16 @@ { "name": "LayoutView #document", "bounds": [800, 600], + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], "contentsOpaque": true, "backgroundColor": "#FFFFFF", "paintInvalidations": [
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt index e2d637f..906a467 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt
@@ -19,12 +19,12 @@ { "object": "LayoutView #document", "rect": [3, 65, 250, 250], - "reason": "subtree" + "reason": "full" }, { "object": "LayoutBlockFlow BODY", "rect": [3, 65, 235, 235], - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutView #document", @@ -32,14 +32,9 @@ "reason": "scroll control" }, { - "object": "LayoutBlockFlow HTML", - "rect": [3, 65, 225, 235], - "reason": "subtree" - }, - { "object": "LayoutText #text", "rect": [3, 65, 55, 17], - "reason": "subtree" + "reason": "appeared" }, { "object": "LayoutView #document", @@ -52,7 +47,7 @@ "objectPaintInvalidations": [ { "object": "LayoutView #document", - "reason": "subtree" + "reason": "full" }, { "object": "HorizontalScrollbar", @@ -64,23 +59,23 @@ }, { "object": "LayoutBlockFlow HTML", - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow BODY", - "reason": "subtree" + "reason": "geometry" }, { "object": "RootInlineBox", - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutText #text", - "reason": "subtree" + "reason": "appeared" }, { "object": "InlineTextBox 'scroll me'", - "reason": "subtree" + "reason": "appeared" } ] }
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/compositing/reflections/nested-reflection-on-overflow-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/compositing/reflections/nested-reflection-on-overflow-expected.txt new file mode 100644 index 0000000..d406bc0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/compositing/reflections/nested-reflection-on-overflow-expected.txt
@@ -0,0 +1,40 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x306 + LayoutBlockFlow {HTML} at (0,0) size 800x306 + LayoutBlockFlow {BODY} at (8,16) size 784x270 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 456x18 + text run at (0,0) width 456: "You should see the original and three copies of the green box with text." +layer at (28,54) size 122x232 + LayoutBlockFlow {DIV} at (20,38) size 122x232 [border: (1px solid #000000)] +layer at (39,65) size 100x100 + LayoutBlockFlow {DIV} at (11,11) size 100x100 [bgcolor=#008000] +layer at (39,65) size 100x100 clip at (39,65) size 85x85 scrollHeight 500 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 100x100 +layer at (39,65) size 85x500 backgroundClip at (39,65) size 85x85 clip at (39,65) size 85x85 + LayoutBlockFlow {DIV} at (0,0) size 85x500 + LayoutText {#text} at (0,0) size 83x414 + text run at (0,0) width 43: "Lorem" + text run at (0,18) width 77: "ipsum dolor" + text run at (0,36) width 55: "sit amet," + text run at (0,54) width 73: "consectetur" + text run at (0,72) width 71: "adipisicing" + text run at (0,90) width 70: "elit, sed do" + text run at (0,108) width 55: "eiusmod" + text run at (0,126) width 46: "tempor" + text run at (0,144) width 82: "incididunt ut" + text run at (0,162) width 56: "labore et" + text run at (0,180) width 41: "dolore" + text run at (0,198) width 43: "magna" + text run at (0,216) width 64: "aliqua. Ut" + text run at (0,234) width 52: "enim ad" + text run at (0,252) width 42: "minim" + text run at (0,270) width 82: "veniam, quis" + text run at (0,288) width 48: "nostrud" + text run at (0,306) width 76: "exercitation" + text run at (0,324) width 52: "ullamco" + text run at (0,342) width 71: "laboris nisi" + text run at (0,360) width 80: "ut aliquip ex" + text run at (0,378) width 83: "ea commodo" + text run at (0,396) width 68: "consequat."
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/css/css-color/color-function-parsing-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/css/css-color/color-function-parsing-expected.txt new file mode 100644 index 0000000..048d173 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/css/css-color/color-function-parsing-expected.txt
@@ -0,0 +1,33 @@ +This is a testharness.js-based test. +FAIL Basic sRGB white assert_equals: expected "color(srgb 1 1 1)" but got "rgb(0, 0, 0)" +FAIL White with lots of space assert_equals: expected "color(srgb 1 1 1)" but got "rgb(0, 0, 0)" +FAIL sRGB color assert_equals: expected "color(srgb 0.25 0.5 0.75)" but got "rgb(0, 0, 0)" +FAIL Different case for sRGB assert_equals: expected "color(srgb 0.25 0.5 0.75)" but got "rgb(0, 0, 0)" +FAIL sRGB color with unnecessary decimals assert_equals: expected "color(srgb 1 0.5 0.2)" but got "rgb(0, 0, 0)" +FAIL sRGB white with 0.5 alpha assert_equals: expected "color(srgb 1 1 1 / 0.5)" but got "rgb(0, 0, 0)" +FAIL sRGB white with 0 alpha assert_equals: expected "color(srgb 1 1 1 / 0)" but got "rgb(0, 0, 0)" +FAIL sRGB white with 50% alpha assert_equals: expected "color(srgb 1 1 1 / 0.5)" but got "rgb(0, 0, 0)" +FAIL sRGB white with 0% alpha assert_equals: expected "color(srgb 1 1 1 / 0)" but got "rgb(0, 0, 0)" +FAIL One missing component is 0 assert_equals: expected "color(srgb 1 1 0)" but got "rgb(0, 0, 0)" +FAIL Two missing components are 0 assert_equals: expected "color(srgb 1 0 0)" but got "rgb(0, 0, 0)" +FAIL All components missing assert_equals: expected "color(srgb 0 0 0)" but got "rgb(0, 0, 0)" +FAIL Display P3 color assert_equals: expected "color(display-p3 0.6 0.7 0.8)" but got "rgb(0, 0, 0)" +FAIL Different case for Display P3 assert_equals: expected "color(display-p3 0.6 0.7 0.8)" but got "rgb(0, 0, 0)" +FAIL Unknown color space should fallback assert_equals: expected "color(unknown 1 2 3, red)" but got "rgb(0, 0, 0)" +FAIL sRGB color with negative component should clamp to 0 assert_equals: expected "color(srgb 0 0.5 0.75)" but got "rgb(0, 0, 0)" +FAIL sRGB color with component > 1 should clamp assert_equals: expected "color(srgb 0.25 1 0.75)" but got "rgb(0, 0, 0)" +FAIL Display P3 color with negative component should clamp to 0 assert_equals: expected "color(display-p3 0.5 0 0.75)" but got "rgb(0, 0, 0)" +FAIL Display P3 color with component > 1 should clamp assert_equals: expected "color(display-p3 1 1 1)" but got "rgb(0, 0, 0)" +FAIL Alpha > 1 should clamp assert_equals: expected "color(srgb 0.1 0.2 0.3)" but got "rgb(0, 0, 0)" +FAIL Negative alpha should clamp assert_equals: expected "color(srgb 1 1 1 / 0)" but got "rgb(0, 0, 0)" +PASS Empty +PASS Bad color space +PASS Bad Display P3 color space +PASS No color space +PASS Too many parameters +PASS Way too many parameters +PASS Bad parameters +PASS Bad alpha +PASS Junk after alpha +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/background/body-background-image-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/background/body-background-image-expected.txt new file mode 100644 index 0000000..22510b3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/background/body-background-image-expected.txt
@@ -0,0 +1,45 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "backgroundColor": "#FFFFFF", + "paintInvalidations": [ + { + "object": "LayoutView #document", + "rect": [0, 0, 800, 600], + "reason": "style change" + } + ] + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow BODY", + "rect": [8, 240, 784, 284], + "reason": "style change" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutView #document", + "reason": "style change" + }, + { + "object": "LayoutBlockFlow BODY", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/reflection/reflection-with-rotation-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/reflection/reflection-with-rotation-expected.txt new file mode 100644 index 0000000..972d0f4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/reflection/reflection-with-rotation-expected.txt
@@ -0,0 +1,51 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target'", + "rect": [22, 50, 226, 167], + "reason": "geometry" + }, + { + "object": "LayoutText #text", + "rect": [23, 51, 71, 109], + "reason": "full" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target'", + "reason": "geometry" + }, + { + "object": "RootInlineBox", + "reason": "geometry" + }, + { + "object": "LayoutText #text", + "reason": "full" + }, + { + "object": "InlineTextBox 'PASS'", + "reason": "full" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt new file mode 100644 index 0000000..9ce7ba58 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt
@@ -0,0 +1,82 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "backgroundColor": "#C0C0C0" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#C0C0C0", + "paintInvalidations": [ + { + "object": "LayoutView #document", + "rect": [3, 65, 250, 250], + "reason": "full" + }, + { + "object": "LayoutBlockFlow BODY", + "rect": [3, 65, 235, 235], + "reason": "geometry" + }, + { + "object": "LayoutView #document", + "rect": [3, 300, 235, 15], + "reason": "scroll control" + }, + { + "object": "LayoutText #text", + "rect": [3, 65, 58, 16], + "reason": "appeared" + }, + { + "object": "LayoutView #document", + "rect": [238, 65, 15, 235], + "reason": "scroll control" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutView #document", + "reason": "full" + }, + { + "object": "HorizontalScrollbar", + "reason": "scroll control" + }, + { + "object": "VerticalScrollbar", + "reason": "scroll control" + }, + { + "object": "LayoutBlockFlow HTML", + "reason": "geometry" + }, + { + "object": "LayoutBlockFlow BODY", + "reason": "geometry" + }, + { + "object": "RootInlineBox", + "reason": "geometry" + }, + { + "object": "LayoutText #text", + "reason": "appeared" + }, + { + "object": "InlineTextBox 'scroll me'", + "reason": "appeared" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/reflections/nested-reflection-on-overflow-expected.txt b/third_party/WebKit/LayoutTests/platform/win/compositing/reflections/nested-reflection-on-overflow-expected.txt index 46513e448..55a5c48 100644 --- a/third_party/WebKit/LayoutTests/platform/win/compositing/reflections/nested-reflection-on-overflow-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/reflections/nested-reflection-on-overflow-expected.txt
@@ -12,7 +12,7 @@ LayoutBlockFlow {DIV} at (11,11) size 100x100 [bgcolor=#008000] layer at (39,67) size 100x100 clip at (39,67) size 85x85 scrollHeight 500 LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 100x100 -layer at (39,67) size 85x500 backgroundClip at (39,67) size 232x210 clip at (39,67) size 232x210 +layer at (39,67) size 85x500 backgroundClip at (39,67) size 85x85 clip at (39,67) size 85x85 LayoutBlockFlow {DIV} at (0,0) size 85x500 LayoutText {#text} at (0,0) size 85x419 text run at (0,0) width 79: "Lorem ipsum"
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/css/css-color/color-function-parsing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/css/css-color/color-function-parsing-expected.txt new file mode 100644 index 0000000..048d173 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/css/css-color/color-function-parsing-expected.txt
@@ -0,0 +1,33 @@ +This is a testharness.js-based test. +FAIL Basic sRGB white assert_equals: expected "color(srgb 1 1 1)" but got "rgb(0, 0, 0)" +FAIL White with lots of space assert_equals: expected "color(srgb 1 1 1)" but got "rgb(0, 0, 0)" +FAIL sRGB color assert_equals: expected "color(srgb 0.25 0.5 0.75)" but got "rgb(0, 0, 0)" +FAIL Different case for sRGB assert_equals: expected "color(srgb 0.25 0.5 0.75)" but got "rgb(0, 0, 0)" +FAIL sRGB color with unnecessary decimals assert_equals: expected "color(srgb 1 0.5 0.2)" but got "rgb(0, 0, 0)" +FAIL sRGB white with 0.5 alpha assert_equals: expected "color(srgb 1 1 1 / 0.5)" but got "rgb(0, 0, 0)" +FAIL sRGB white with 0 alpha assert_equals: expected "color(srgb 1 1 1 / 0)" but got "rgb(0, 0, 0)" +FAIL sRGB white with 50% alpha assert_equals: expected "color(srgb 1 1 1 / 0.5)" but got "rgb(0, 0, 0)" +FAIL sRGB white with 0% alpha assert_equals: expected "color(srgb 1 1 1 / 0)" but got "rgb(0, 0, 0)" +FAIL One missing component is 0 assert_equals: expected "color(srgb 1 1 0)" but got "rgb(0, 0, 0)" +FAIL Two missing components are 0 assert_equals: expected "color(srgb 1 0 0)" but got "rgb(0, 0, 0)" +FAIL All components missing assert_equals: expected "color(srgb 0 0 0)" but got "rgb(0, 0, 0)" +FAIL Display P3 color assert_equals: expected "color(display-p3 0.6 0.7 0.8)" but got "rgb(0, 0, 0)" +FAIL Different case for Display P3 assert_equals: expected "color(display-p3 0.6 0.7 0.8)" but got "rgb(0, 0, 0)" +FAIL Unknown color space should fallback assert_equals: expected "color(unknown 1 2 3, red)" but got "rgb(0, 0, 0)" +FAIL sRGB color with negative component should clamp to 0 assert_equals: expected "color(srgb 0 0.5 0.75)" but got "rgb(0, 0, 0)" +FAIL sRGB color with component > 1 should clamp assert_equals: expected "color(srgb 0.25 1 0.75)" but got "rgb(0, 0, 0)" +FAIL Display P3 color with negative component should clamp to 0 assert_equals: expected "color(display-p3 0.5 0 0.75)" but got "rgb(0, 0, 0)" +FAIL Display P3 color with component > 1 should clamp assert_equals: expected "color(display-p3 1 1 1)" but got "rgb(0, 0, 0)" +FAIL Alpha > 1 should clamp assert_equals: expected "color(srgb 0.1 0.2 0.3)" but got "rgb(0, 0, 0)" +FAIL Negative alpha should clamp assert_equals: expected "color(srgb 1 1 1 / 0)" but got "rgb(0, 0, 0)" +PASS Empty +PASS Bad color space +PASS Bad Display P3 color space +PASS No color space +PASS Too many parameters +PASS Way too many parameters +PASS Bad parameters +PASS Bad alpha +PASS Junk after alpha +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/background/body-background-image-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/background/body-background-image-expected.txt index 2ab0744..cdbd30c5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/background/body-background-image-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/background/body-background-image-expected.txt
@@ -24,11 +24,6 @@ "backgroundColor": "#FFFFFF", "paintInvalidations": [ { - "object": "LayoutView #document", - "rect": [0, 0, 800, 600], - "reason": "style change" - }, - { "object": "LayoutBlockFlow BODY", "rect": [8, 240, 784, 288], "reason": "style change"
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/reflection/reflection-with-rotation-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/reflection/reflection-with-rotation-expected.txt new file mode 100644 index 0000000..972d0f4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/reflection/reflection-with-rotation-expected.txt
@@ -0,0 +1,51 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target'", + "rect": [22, 50, 226, 167], + "reason": "geometry" + }, + { + "object": "LayoutText #text", + "rect": [23, 51, 71, 109], + "reason": "full" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target'", + "reason": "geometry" + }, + { + "object": "RootInlineBox", + "reason": "geometry" + }, + { + "object": "LayoutText #text", + "reason": "full" + }, + { + "object": "InlineTextBox 'PASS'", + "reason": "full" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt index 1b0eeb5..eedb2fa95 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/scroll/repaint-during-scroll-with-zoom-expected.txt
@@ -19,12 +19,12 @@ { "object": "LayoutView #document", "rect": [3, 65, 250, 250], - "reason": "subtree" + "reason": "full" }, { "object": "LayoutBlockFlow BODY", "rect": [3, 65, 235, 235], - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutView #document", @@ -32,14 +32,9 @@ "reason": "scroll control" }, { - "object": "LayoutBlockFlow HTML", - "rect": [3, 65, 225, 235], - "reason": "subtree" - }, - { "object": "LayoutText #text", "rect": [3, 65, 52, 17], - "reason": "subtree" + "reason": "appeared" }, { "object": "LayoutView #document", @@ -52,7 +47,7 @@ "objectPaintInvalidations": [ { "object": "LayoutView #document", - "reason": "subtree" + "reason": "full" }, { "object": "HorizontalScrollbar", @@ -64,23 +59,23 @@ }, { "object": "LayoutBlockFlow HTML", - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutBlockFlow BODY", - "reason": "subtree" + "reason": "geometry" }, { "object": "RootInlineBox", - "reason": "subtree" + "reason": "geometry" }, { "object": "LayoutText #text", - "reason": "subtree" + "reason": "appeared" }, { "object": "InlineTextBox 'scroll me'", - "reason": "subtree" + "reason": "appeared" } ] }
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/transform.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/transform.html index 114b289e..0e14760 100644 --- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/transform.html +++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/transform.html
@@ -35,7 +35,7 @@ new CSSTransformValue([new CSSScale(1, 2.2, 3)]), new CSSTransformValue([new CSSScale(-1, -2.2)]), new CSSTransformValue([new CSSScale(-1, -2.2, -3)]), - // Skews + // Skew new CSSTransformValue([new CSSSkew(CSS.deg(30), CSS.deg(0))]), new CSSTransformValue([new CSSSkew(CSS.rad(10), CSS.deg(0))]), new CSSTransformValue([new CSSSkew(CSS.grad(2), CSS.deg(0))]), @@ -49,6 +49,11 @@ new CSSTransformValue([new CSSSkewX(CSS.rad(10))]), new CSSTransformValue([new CSSSkewX(CSS.grad(2))]), new CSSTransformValue([new CSSSkewX(CSS.turn(0.2))]), + // SkewY + new CSSTransformValue([new CSSSkewY(CSS.deg(10))]), + new CSSTransformValue([new CSSSkewY(CSS.rad(30))]), + new CSSTransformValue([new CSSSkewY(CSS.grad(20))]), + new CSSTransformValue([new CSSSkewY(CSS.turn(0.5))]), // Rotations cssTransformWithRotate(CSS.deg(30)), cssTransformWithRotate(CSS.rad(10)), @@ -95,12 +100,12 @@ 'skewX(0.31turn)': new CSSTransformValue([new CSSSkewX(CSS.turn(0.31))]), 'skewY(45deg)': - new CSSTransformValue([new CSSSkew(CSS.deg(0), CSS.deg(45))]), - 'skewY(1rad)': new CSSTransformValue([new CSSSkew(CSS.deg(0), CSS.rad(1))]), + new CSSTransformValue([new CSSSkewY(CSS.deg(45))]), + 'skewY(1rad)': new CSSTransformValue([new CSSSkewY(CSS.rad(1))]), 'skewY(6.2grad)': - new CSSTransformValue([new CSSSkew(CSS.deg(0), CSS.grad(6.2))]), + new CSSTransformValue([new CSSSkewY(CSS.grad(6.2))]), 'skewY(0.31turn)': - new CSSTransformValue([new CSSSkew(CSS.deg(0), CSS.turn(0.31))]), + new CSSTransformValue([new CSSSkewY(CSS.turn(0.31))]), // Rotations 'rotateX(45deg)': cssTransformWithRotate3D(1, 0, 0, CSS.deg(45)), 'rotateX(1rad)': cssTransformWithRotate3D(1, 0, 0, CSS.rad(1)),
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/compositing/reflections/nested-reflection-on-overflow-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/compositing/reflections/nested-reflection-on-overflow-expected.txt index 4f2cdbe..92c1af3 100644 --- a/third_party/WebKit/LayoutTests/virtual/spv175/compositing/reflections/nested-reflection-on-overflow-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/spv175/compositing/reflections/nested-reflection-on-overflow-expected.txt
@@ -12,7 +12,7 @@ LayoutBlockFlow {DIV} at (11,11) size 100x100 [bgcolor=#008000] layer at (39,67) size 100x100 clip at (39,67) size 85x85 scrollHeight 500 LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 100x100 -layer at (39,67) size 85x500 backgroundClip at (39,67) size 232x210 clip at (39,67) size 232x210 +layer at (39,67) size 85x500 backgroundClip at (39,67) size 85x85 clip at (39,67) size 85x85 LayoutBlockFlow {DIV} at (0,0) size 85x500 LayoutText {#text} at (0,0) size 84x459 text run at (0,0) width 84: "Lorem ipsum"
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings-expected.txt index 172d137..123fb548 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings-expected.txt
@@ -1,6 +1,5 @@ CONSOLE ERROR: line 39: [audit.js] this test requires the explicit comparison with the expected result when it runs with run-webkit-tests. CONSOLE MESSAGE: line 129: Test: test-0 -CONSOLE WARNING: line 135: AudioParam value setter will become equivalent to AudioParam.setValueAtTime() in M65, around March 2018 See https://webaudio.github.io/web-audio-api/#dom-audioparam-value for more details. CONSOLE MESSAGE: line 129: Test: test-1 CONSOLE MESSAGE: line 129: Test: test-2 CONSOLE MESSAGE: line 129: Test: test-3
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 465e2401..979dbc2 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -659,9 +659,9 @@ [Worker] method constructor [Worker] interface LockManager [Worker] attribute @@toStringTag -[Worker] method acquire [Worker] method constructor [Worker] method query +[Worker] method request [Worker] interface MessageChannel [Worker] attribute @@toStringTag [Worker] getter port1
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index fd5ccdc..a298fd8 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -798,6 +798,11 @@ getter ax method constructor setter ax +interface CSSSkewY : CSSTransformComponent + attribute @@toStringTag + getter ay + method constructor + setter ay interface CSSStyleDeclaration attribute @@toStringTag getter cssFloat @@ -4026,9 +4031,9 @@ method constructor interface LockManager attribute @@toStringTag - method acquire method constructor method query + method request interface MIDIAccess : EventTarget attribute @@toStringTag getter inputs
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt index 1c10d2d..ebd838a 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -654,9 +654,9 @@ [Worker] method constructor [Worker] interface LockManager [Worker] attribute @@toStringTag -[Worker] method acquire [Worker] method constructor [Worker] method query +[Worker] method request [Worker] interface MessageChannel [Worker] attribute @@toStringTag [Worker] getter port1
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index 157b37b5..50dfe1f 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -94,7 +94,6 @@ "//third_party/libwebp", "//third_party/libxml", "//third_party/libxslt", - "//third_party/sqlite", # FIXME: don't depend on bindings/modules http://crbug.com/358074 "//third_party/WebKit/Source/bindings/modules:bindings_modules_generated", @@ -124,7 +123,6 @@ "//third_party/libxslt", "//third_party/ots", "//third_party/snappy", - "//third_party/sqlite", "//third_party/zlib", "//ui/gfx/geometry", "//url", @@ -1599,7 +1597,6 @@ "//third_party/libwebp", "//third_party/libxml", "//third_party/libxslt", - "//third_party/sqlite", # FIXME: don't depend on bindings/modules http://crbug.com/358074 "//third_party/WebKit/Source/bindings/modules:bindings_modules_generated",
diff --git a/third_party/WebKit/Source/core/animation/AnimationTest.cpp b/third_party/WebKit/Source/core/animation/AnimationTest.cpp index 62307c77..40b9ea5 100644 --- a/third_party/WebKit/Source/core/animation/AnimationTest.cpp +++ b/third_party/WebKit/Source/core/animation/AnimationTest.cpp
@@ -708,7 +708,7 @@ } TEST_F(AnimationAnimationTest, AttachedAnimations) { - Persistent<Element> element = document->createElement("foo"); + Persistent<Element> element = document->CreateElementForBinding("foo"); Timing timing; KeyframeEffect* keyframe_effect =
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp index 58a7c5a..b20385e 100644 --- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp +++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
@@ -115,7 +115,7 @@ timeline_ = DocumentTimeline::Create(&GetDocument()); timeline_->ResetForTesting(); - element_ = GetDocument().createElement("test"); + element_ = GetDocument().CreateElementForBinding("test"); helper_.Initialize(nullptr, nullptr, nullptr, &ConfigureSettings); base_url_ = "http://www.test.com/"; @@ -1150,7 +1150,7 @@ TEST_F(AnimationCompositorAnimationsTest, cancelIncompatibleCompositorAnimations) { - Persistent<Element> element = GetDocument().createElement("shared"); + Persistent<Element> element = GetDocument().CreateElementForBinding("shared"); LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get()); element->SetLayoutObject(layout_object); @@ -1240,7 +1240,7 @@ TEST_F(AnimationCompositorAnimationsTest, canStartElementOnCompositorTransformSPv2) { - Persistent<Element> element = GetDocument().createElement("shared"); + Persistent<Element> element = GetDocument().CreateElementForBinding("shared"); LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get()); element->SetLayoutObject(layout_object); @@ -1272,7 +1272,7 @@ TEST_F(AnimationCompositorAnimationsTest, canStartElementOnCompositorEffectSPv2) { - Persistent<Element> element = GetDocument().createElement("shared"); + Persistent<Element> element = GetDocument().CreateElementForBinding("shared"); LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get()); element->SetLayoutObject(layout_object);
diff --git a/third_party/WebKit/Source/core/animation/EffectInputTest.cpp b/third_party/WebKit/Source/core/animation/EffectInputTest.cpp index c69b8f25..de1e7d83 100644 --- a/third_party/WebKit/Source/core/animation/EffectInputTest.cpp +++ b/third_party/WebKit/Source/core/animation/EffectInputTest.cpp
@@ -20,7 +20,7 @@ namespace blink { Element* AppendElement(Document& document) { - Element* element = document.createElement("foo"); + Element* element = document.CreateElementForBinding("foo"); document.documentElement()->AppendChild(element); return element; }
diff --git a/third_party/WebKit/Source/core/animation/EffectStackTest.cpp b/third_party/WebKit/Source/core/animation/EffectStackTest.cpp index 1e02d245..81cecf90 100644 --- a/third_party/WebKit/Source/core/animation/EffectStackTest.cpp +++ b/third_party/WebKit/Source/core/animation/EffectStackTest.cpp
@@ -25,7 +25,7 @@ PageTestBase::SetUp(IntSize()); GetDocument().GetAnimationClock().ResetTimeForTesting(); timeline = DocumentTimeline::Create(&GetDocument()); - element = GetDocument().createElement("foo"); + element = GetDocument().CreateElementForBinding("foo"); } Animation* Play(KeyframeEffect* effect, double start_time) {
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp b/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp index 1ec83c8..7b430038 100644 --- a/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp +++ b/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp
@@ -47,7 +47,7 @@ protected: void SetUp() override { PageTestBase::SetUp(IntSize()); - element = GetDocument().createElement("foo"); + element = GetDocument().CreateElementForBinding("foo"); } void ExpectLengthValue(double expected_value,
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp b/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp index 3d8fb14..30b6c68 100644 --- a/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp +++ b/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp
@@ -28,7 +28,7 @@ protected: virtual void SetUp() { PageTestBase::SetUp(IntSize()); - element = GetDocument().createElement("foo"); + element = GetDocument().CreateElementForBinding("foo"); GetDocument().GetAnimationClock().ResetTimeForTesting( GetDocument().Timeline().ZeroTime());
diff --git a/third_party/WebKit/Source/core/core_idl_files.gni b/third_party/WebKit/Source/core/core_idl_files.gni index 5423a9e..f829ba4 100644 --- a/third_party/WebKit/Source/core/core_idl_files.gni +++ b/third_party/WebKit/Source/core/core_idl_files.gni
@@ -91,6 +91,7 @@ "css/cssom/CSSScale.idl", "css/cssom/CSSSkew.idl", "css/cssom/CSSSkewX.idl", + "css/cssom/CSSSkewY.idl", "css/cssom/CSSStyleValue.idl", "css/cssom/CSSTransformComponent.idl", "css/cssom/CSSTransformValue.idl",
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn index 91f7a7a..dbe6bd8 100644 --- a/third_party/WebKit/Source/core/css/BUILD.gn +++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -344,6 +344,8 @@ "cssom/CSSSkew.h", "cssom/CSSSkewX.cpp", "cssom/CSSSkewX.h", + "cssom/CSSSkewY.cpp", + "cssom/CSSSkewY.h", "cssom/CSSStyleImageValue.cpp", "cssom/CSSStyleImageValue.h", "cssom/CSSStyleValue.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h index 3c21b9c..325cb3a 100644 --- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h +++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -1583,6 +1583,9 @@ inline CSSIdentifierValue::CSSIdentifierValue(ItemPosition item_position) : CSSValue(kIdentifierClass) { switch (item_position) { + case ItemPosition::kLegacy: + value_id_ = CSSValueLegacy; + break; case ItemPosition::kAuto: value_id_ = CSSValueAuto; break; @@ -1631,6 +1634,8 @@ template <> inline ItemPosition CSSIdentifierValue::ConvertTo() const { switch (value_id_) { + case CSSValueLegacy: + return ItemPosition::kLegacy; case CSSValueAuto: return ItemPosition::kAuto; case CSSValueNormal:
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index f4f33fc2a..c9ab7b94 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -1561,7 +1561,7 @@ field_group: "*", field_template: "external", include_paths: ["core/style/StyleSelfAlignmentData.h"], - default_value: "StyleSelfAlignmentData(ItemPosition::kAuto, OverflowAlignment::kDefault)", + default_value: "StyleSelfAlignmentData(ItemPosition::kLegacy, OverflowAlignment::kDefault)", type_name: "StyleSelfAlignmentData", converter: "ConvertSelfOrDefaultAlignmentData", },
diff --git a/third_party/WebKit/Source/core/css/SelectorQueryTest.cpp b/third_party/WebKit/Source/core/css/SelectorQueryTest.cpp index 287fbc5..a40b80b 100644 --- a/third_party/WebKit/Source/core/css/SelectorQueryTest.cpp +++ b/third_party/WebKit/Source/core/css/SelectorQueryTest.cpp
@@ -328,7 +328,7 @@ TEST(SelectorQueryTest, DisconnectedSubtree) { Document* document = HTMLDocument::CreateForTest(); - Element* scope = document->createElement("div"); + Element* scope = document->CreateRawElement(HTMLNames::divTag); scope->SetInnerHTMLFromString(R"HTML( <section> <span id=first> @@ -355,7 +355,7 @@ TEST(SelectorQueryTest, DisconnectedTreeScope) { Document* document = HTMLDocument::CreateForTest(); - Element* host = document->createElement("div"); + Element* host = document->CreateRawElement(HTMLNames::divTag); // TODO(esprehn): Element::attachShadow() should not require a ScriptState, // it should handle the use counting in the bindings layer instead of in the // C++.
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSSkew.cpp b/third_party/WebKit/Source/core/css/cssom/CSSSkew.cpp index 9783253e..52afb1b4 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSSkew.cpp +++ b/third_party/WebKit/Source/core/css/cssom/CSSSkew.cpp
@@ -52,28 +52,18 @@ CSSSkew* CSSSkew::FromCSSValue(const CSSFunctionValue& value) { DCHECK_GT(value.length(), 0U); const CSSPrimitiveValue& x_value = ToCSSPrimitiveValue(value.Item(0)); - switch (value.FunctionType()) { - case CSSValueSkew: - if (value.length() == 1U) { - return CSSSkew::Create( - CSSNumericValue::FromCSSValue(x_value), - CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kDegrees)); - } else if (value.length() == 2U) { - const CSSPrimitiveValue& y_value = ToCSSPrimitiveValue(value.Item(1)); - return CSSSkew::Create(CSSNumericValue::FromCSSValue(x_value), - CSSNumericValue::FromCSSValue(y_value)); - } - NOTREACHED(); - return nullptr; - case CSSValueSkewY: - DCHECK_EQ(value.length(), 1U); - return CSSSkew::Create( - CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kDegrees), - CSSNumericValue::FromCSSValue(x_value)); - default: - NOTREACHED(); - return nullptr; + DCHECK_EQ(value.FunctionType(), CSSValueSkew); + if (value.length() == 1U) { + return CSSSkew::Create( + CSSNumericValue::FromCSSValue(x_value), + CSSUnitValue::Create(0, CSSPrimitiveValue::UnitType::kDegrees)); + } else if (value.length() == 2U) { + const CSSPrimitiveValue& y_value = ToCSSPrimitiveValue(value.Item(1)); + return CSSSkew::Create(CSSNumericValue::FromCSSValue(x_value), + CSSNumericValue::FromCSSValue(y_value)); } + NOTREACHED(); + return nullptr; } const DOMMatrix* CSSSkew::AsMatrix(ExceptionState&) const {
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSSkew.h b/third_party/WebKit/Source/core/css/cssom/CSSSkew.h index dfc6c7d..7293af41 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSSkew.h +++ b/third_party/WebKit/Source/core/css/cssom/CSSSkew.h
@@ -27,7 +27,7 @@ return new CSSSkew(ax, ay); } - // Internal ways of creating CSSSkews. + // Internal ways of creating CSSSkew. static CSSSkew* FromCSSValue(const CSSFunctionValue&); // Getters and setters for the ax and ay attributes defined in the IDL.
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSSkewX.cpp b/third_party/WebKit/Source/core/css/cssom/CSSSkewX.cpp index aee80bb..186ae90 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSSkewX.cpp +++ b/third_party/WebKit/Source/core/css/cssom/CSSSkewX.cpp
@@ -42,15 +42,13 @@ CSSSkewX* CSSSkewX::FromCSSValue(const CSSFunctionValue& value) { DCHECK_GT(value.length(), 0U); - switch (value.FunctionType()) { - case CSSValueSkewX: - DCHECK_EQ(value.length(), 1U); - return CSSSkewX::Create( - CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(0)))); - default: - NOTREACHED(); - return nullptr; + DCHECK_EQ(value.FunctionType(), CSSValueSkewX); + if (value.length() == 1U) { + return CSSSkewX::Create( + CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(0)))); } + NOTREACHED(); + return nullptr; } const DOMMatrix* CSSSkewX::AsMatrix(ExceptionState&) const {
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSSkewY.cpp b/third_party/WebKit/Source/core/css/cssom/CSSSkewY.cpp new file mode 100644 index 0000000..7f73981 --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/CSSSkewY.cpp
@@ -0,0 +1,77 @@ +// Copyright 2018 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 "core/css/cssom/CSSSkewY.h" + +#include "bindings/core/v8/ExceptionState.h" +#include "core/css/CSSFunctionValue.h" +#include "core/css/CSSPrimitiveValue.h" +#include "core/css/cssom/CSSNumericValue.h" +#include "core/css/cssom/CSSStyleValue.h" +#include "core/css/cssom/CSSUnitValue.h" +#include "core/geometry/DOMMatrix.h" + +namespace blink { + +namespace { + +bool IsValidSkewYAngle(CSSNumericValue* value) { + return value && + value->Type().MatchesBaseType(CSSNumericValueType::BaseType::kAngle); +} + +} // namespace + +CSSSkewY* CSSSkewY::Create(CSSNumericValue* ay, + ExceptionState& exception_state) { + if (!IsValidSkewYAngle(ay)) { + exception_state.ThrowTypeError("CSSSkewY does not support non-angles"); + return nullptr; + } + return new CSSSkewY(ay); +} + +void CSSSkewY::setAy(CSSNumericValue* value, ExceptionState& exception_state) { + if (!IsValidSkewYAngle(value)) { + exception_state.ThrowTypeError("Must specify an angle unit"); + return; + } + ay_ = value; +} + +CSSSkewY* CSSSkewY::FromCSSValue(const CSSFunctionValue& value) { + DCHECK_GT(value.length(), 0U); + DCHECK_EQ(value.FunctionType(), CSSValueSkewY); + if (value.length(), 1U) { + return CSSSkewY::Create( + CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(0)))); + } + NOTREACHED(); + return nullptr; +} + +const DOMMatrix* CSSSkewY::AsMatrix(ExceptionState&) const { + CSSUnitValue* ay = ay_->to(CSSPrimitiveValue::UnitType::kRadians); + DCHECK(ay); + DOMMatrix* result = DOMMatrix::Create(); + result->setM12(std::tan(ay->value())); + return result; +} + +const CSSFunctionValue* CSSSkewY::ToCSSValue() const { + const CSSValue* ay = ay_->ToCSSValue(); + if (!ay) + return nullptr; + + CSSFunctionValue* result = CSSFunctionValue::Create(CSSValueSkewY); + result->Append(*ay); + return result; +} + +CSSSkewY::CSSSkewY(CSSNumericValue* ay) + : CSSTransformComponent(true /* is2D */), ay_(ay) { + DCHECK(ay); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSSkewY.h b/third_party/WebKit/Source/core/css/cssom/CSSSkewY.h new file mode 100644 index 0000000..68aeef32 --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/CSSSkewY.h
@@ -0,0 +1,59 @@ +// Copyright 2018 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 CSSSkewY_h +#define CSSSkewY_h + +#include "base/macros.h" +#include "core/css/cssom/CSSNumericValue.h" +#include "core/css/cssom/CSSTransformComponent.h" + +namespace blink { + +class DOMMatrix; +class ExceptionState; + +// Represents a skewY value in a CSSTransformValue used for properties like +// "transform". +// See CSSSkewY.idl for more information about this class. +class CORE_EXPORT CSSSkewY final : public CSSTransformComponent { + DEFINE_WRAPPERTYPEINFO(); + + public: + // Constructor defined in the IDL. + static CSSSkewY* Create(CSSNumericValue*, ExceptionState&); + static CSSSkewY* Create(CSSNumericValue* ay) { return new CSSSkewY(ay); } + + // Internal ways of creating CSSSkewY. + static CSSSkewY* FromCSSValue(const CSSFunctionValue&); + + // Getters and setters for the ay attributes defined in the IDL. + CSSNumericValue* ay() { return ay_.Get(); } + void setAy(CSSNumericValue*, ExceptionState&); + + // From CSSTransformComponent + // Setting is2D for CSSSkewY does nothing. + // https://drafts.css-houdini.org/css-typed-om/#dom-cssskew-is2d + void setIs2D(bool is2D) final {} + + // Internal methods - from CSSTransformComponent. + const DOMMatrix* AsMatrix(ExceptionState&) const override; + TransformComponentType GetType() const override { return kSkewYType; } + const CSSFunctionValue* ToCSSValue() const override; + + virtual void Trace(blink::Visitor* visitor) { + visitor->Trace(ay_); + CSSTransformComponent::Trace(visitor); + } + + private: + CSSSkewY(CSSNumericValue* ay); + + Member<CSSNumericValue> ay_; + DISALLOW_COPY_AND_ASSIGN(CSSSkewY); +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSSkewY.idl b/third_party/WebKit/Source/core/css/cssom/CSSSkewY.idl new file mode 100644 index 0000000..1419e31d --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/CSSSkewY.idl
@@ -0,0 +1,15 @@ +// Copyright 2018 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. + +// Represents a skewX value in a CSSTransformValue used for properties like +// "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om-1/#cssskewy +[ + Constructor(CSSNumericValue ay), + Exposed=(Window, Worker, PaintWorklet, LayoutWorklet), + RuntimeEnabled=CSSTypedOM, + RaisesException=Constructor] +interface CSSSkewY : CSSTransformComponent { + [RaisesException=Setter] attribute CSSNumericValue ay; +}; \ No newline at end of file
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.cpp b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.cpp index 5f82372f..915e8a3 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.cpp +++ b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.cpp
@@ -10,6 +10,7 @@ #include "core/css/cssom/CSSScale.h" #include "core/css/cssom/CSSSkew.h" #include "core/css/cssom/CSSSkewX.h" +#include "core/css/cssom/CSSSkewY.h" #include "core/css/cssom/CSSTranslate.h" namespace blink { @@ -39,10 +40,11 @@ case CSSValueScale3d: return CSSScale::FromCSSValue(function_value); case CSSValueSkew: - case CSSValueSkewY: return CSSSkew::FromCSSValue(function_value); case CSSValueSkewX: return CSSSkewX::FromCSSValue(function_value); + case CSSValueSkewY: + return CSSSkewY::FromCSSValue(function_value); case CSSValueTranslate: case CSSValueTranslateX: case CSSValueTranslateY:
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.h b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.h index d6013999..a083fa6ad 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.h +++ b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.h
@@ -31,6 +31,7 @@ kScaleType, kSkewType, kSkewXType, + kSkewYType, kTranslationType, };
diff --git a/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.cpp index 13630c3..2575d046 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.cpp
@@ -57,8 +57,12 @@ id); } -bool IsAutoOrNormalOrStretch(CSSValueID id) { - return CSSPropertyParserHelpers::IdentMatches<CSSValueAuto, CSSValueNormal, +bool IsAuto(CSSValueID id) { + return CSSPropertyParserHelpers::IdentMatches<CSSValueAuto>(id); +} + +bool IsNormalOrStretch(CSSValueID id) { + return CSSPropertyParserHelpers::IdentMatches<CSSValueNormal, CSSValueStretch>(id); } @@ -548,7 +552,7 @@ IsPositionKeyword is_position_keyword) { DCHECK(is_position_keyword); CSSValueID id = range.Peek().Id(); - if (IsAutoOrNormalOrStretch(id)) + if (IsAuto(id) || IsNormalOrStretch(id)) return CSSPropertyParserHelpers::ConsumeIdent(range); if (IsBaselineKeyword(id)) @@ -566,11 +570,12 @@ return self_position; } -CSSValue* ConsumeSimplifiedItemPosition(CSSParserTokenRange& range, - IsPositionKeyword is_position_keyword) { +CSSValue* ConsumeSimplifiedDefaultPosition( + CSSParserTokenRange& range, + IsPositionKeyword is_position_keyword) { DCHECK(is_position_keyword); CSSValueID id = range.Peek().Id(); - if (IsAutoOrNormalOrStretch(id) || is_position_keyword(id)) + if (IsNormalOrStretch(id) || is_position_keyword(id)) return CSSPropertyParserHelpers::ConsumeIdent(range); if (IsBaselineKeyword(id)) @@ -579,6 +584,14 @@ return nullptr; } +CSSValue* ConsumeSimplifiedSelfPosition(CSSParserTokenRange& range, + IsPositionKeyword is_position_keyword) { + DCHECK(is_position_keyword); + return IsAuto(range.Peek().Id()) + ? CSSPropertyParserHelpers::ConsumeIdent(range) + : ConsumeSimplifiedDefaultPosition(range, is_position_keyword); +} + CSSValue* ConsumeContentDistributionOverflowPosition( CSSParserTokenRange& range, IsPositionKeyword is_position_keyword) { @@ -2385,22 +2398,28 @@ DCHECK(!justify_value); bool is_baseline = IsBaselineKeyword(range.Peek().Id()); - align_value = consume_alignment_value(range, IsSelfPositionKeyword); + bool is_content_alignment = + consume_alignment_value == ConsumeSimplifiedContentPosition; + align_value = consume_alignment_value(range, is_content_alignment + ? IsContentPositionKeyword + : IsSelfPositionKeyword); if (!align_value) return false; // justify-content property does not allow the <baseline-position> values. - if (consume_alignment_value == ConsumeSimplifiedContentPosition) { + if (is_content_alignment) { if (range.AtEnd() && is_baseline) return false; if (IsBaselineKeyword(range.Peek().Id())) return false; } - justify_value = - range.AtEnd() - ? align_value - : consume_alignment_value(range, IsSelfPositionOrLeftOrRightKeyword); + justify_value = range.AtEnd() + ? align_value + : consume_alignment_value( + range, is_content_alignment + ? IsContentPositionOrLeftOrRightKeyword + : IsSelfPositionOrLeftOrRightKeyword); return justify_value && range.AtEnd(); }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.h b/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.h index 1ff911d..9c4bd0fa2 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.h +++ b/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.h
@@ -49,7 +49,9 @@ CSSValue* ConsumeSelfPositionOverflowPosition(CSSParserTokenRange&, IsPositionKeyword); -CSSValue* ConsumeSimplifiedItemPosition(CSSParserTokenRange&, +CSSValue* ConsumeSimplifiedDefaultPosition(CSSParserTokenRange&, + IsPositionKeyword); +CSSValue* ConsumeSimplifiedSelfPosition(CSSParserTokenRange&, IsPositionKeyword); CSSValue* ConsumeContentDistributionOverflowPosition(CSSParserTokenRange&, IsPositionKeyword);
diff --git a/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.cpp b/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.cpp index c0a819b..559f9faa 100644 --- a/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.cpp +++ b/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.cpp
@@ -643,7 +643,10 @@ if (data.GetPosition() >= ItemPosition::kCenter && data.Overflow() != OverflowAlignment::kDefault) result->Append(*CSSIdentifierValue::Create(data.Overflow())); - result->Append(*CSSIdentifierValue::Create(data.GetPosition())); + if (data.GetPosition() == ItemPosition::kLegacy) + result->Append(*CSSIdentifierValue::Create(CSSValueNormal)); + else + result->Append(*CSSIdentifierValue::Create(data.GetPosition())); } DCHECK_LE(result->length(), 2u); return result;
diff --git a/third_party/WebKit/Source/core/css/properties/longhands/JustifyItemsCustom.cpp b/third_party/WebKit/Source/core/css/properties/longhands/JustifyItemsCustom.cpp index f91a3cc..375e822b 100644 --- a/third_party/WebKit/Source/core/css/properties/longhands/JustifyItemsCustom.cpp +++ b/third_party/WebKit/Source/core/css/properties/longhands/JustifyItemsCustom.cpp
@@ -19,6 +19,9 @@ const CSSParserContext& context, const CSSParserLocalContext&) const { CSSParserTokenRange range_copy = range; + // justify-items property does not allow the 'auto' value. + if (CSSPropertyParserHelpers::IdentMatches<CSSValueAuto>(range.Peek().Id())) + return nullptr; CSSIdentifierValue* legacy = CSSPropertyParserHelpers::ConsumeIdent<CSSValueLegacy>(range_copy); CSSIdentifierValue* position_keyword = @@ -26,11 +29,14 @@ CSSValueRight>(range_copy); if (!legacy) legacy = CSSPropertyParserHelpers::ConsumeIdent<CSSValueLegacy>(range_copy); - if (legacy && position_keyword) { + if (legacy) { range = range_copy; - context.Count(WebFeature::kCSSLegacyAlignment); - return CSSValuePair::Create(legacy, position_keyword, - CSSValuePair::kDropIdenticalValues); + if (position_keyword) { + context.Count(WebFeature::kCSSLegacyAlignment); + return CSSValuePair::Create(legacy, position_keyword, + CSSValuePair::kDropIdenticalValues); + } + return legacy; } return CSSParsingUtils::ConsumeSelfPositionOverflowPosition(
diff --git a/third_party/WebKit/Source/core/css/properties/shorthands/PlaceItemsCustom.cpp b/third_party/WebKit/Source/core/css/properties/shorthands/PlaceItemsCustom.cpp index d661c76c..ac01502a 100644 --- a/third_party/WebKit/Source/core/css/properties/shorthands/PlaceItemsCustom.cpp +++ b/third_party/WebKit/Source/core/css/properties/shorthands/PlaceItemsCustom.cpp
@@ -21,14 +21,10 @@ HeapVector<CSSPropertyValue, 256>& properties) const { DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceItems).length(), 2u); - // align-items property does not allow the 'auto' value. - if (CSSPropertyParserHelpers::IdentMatches<CSSValueAuto>(range.Peek().Id())) - return false; - CSSValue* align_items_value = nullptr; CSSValue* justify_items_value = nullptr; if (!CSSParsingUtils::ConsumePlaceAlignment( - range, CSSParsingUtils::ConsumeSimplifiedItemPosition, + range, CSSParsingUtils::ConsumeSimplifiedDefaultPosition, align_items_value, justify_items_value)) return false;
diff --git a/third_party/WebKit/Source/core/css/properties/shorthands/PlaceSelfCustom.cpp b/third_party/WebKit/Source/core/css/properties/shorthands/PlaceSelfCustom.cpp index 534d75b..8b7dc65 100644 --- a/third_party/WebKit/Source/core/css/properties/shorthands/PlaceSelfCustom.cpp +++ b/third_party/WebKit/Source/core/css/properties/shorthands/PlaceSelfCustom.cpp
@@ -23,11 +23,11 @@ CSSValue* align_self_value = nullptr; CSSValue* justify_self_value = nullptr; - if (!CSSParsingUtils::ConsumePlaceAlignment( - range, CSSParsingUtils::ConsumeSimplifiedItemPosition, - align_self_value, justify_self_value)) + range, CSSParsingUtils::ConsumeSimplifiedSelfPosition, + align_self_value, justify_self_value)) { return false; + } DCHECK(align_self_value); DCHECK(justify_self_value);
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp index 82836570..c9b4d67 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
@@ -637,13 +637,12 @@ if (style.GetPosition() == EPosition::kSticky) style.SetSubtreeIsSticky(true); - // If the inherited value of justify-items includes the 'legacy' keyword, - // 'auto' computes to the the inherited value. Otherwise, 'auto' computes to - // 'normal'. - if (style.JustifyItemsPosition() == ItemPosition::kAuto) { - if (parent_style.JustifyItemsPositionType() == ItemPositionType::kLegacy) { - style.SetJustifyItems(parent_style.JustifyItems()); - } + // If the inherited value of justify-items includes the 'legacy' + // keyword (plus 'left', 'right' or 'center'), 'legacy' computes to + // the the inherited value. Otherwise, 'auto' computes to 'normal'. + if (parent_style.JustifyItemsPositionType() == ItemPositionType::kLegacy && + style.JustifyItemsPosition() == ItemPosition::kLegacy) { + style.SetJustifyItems(parent_style.JustifyItems()); } AdjustEffectiveTouchAction(style, parent_style, element, is_svg_root);
diff --git a/third_party/WebKit/Source/core/dom/ComputedAccessibleNode.cpp b/third_party/WebKit/Source/core/dom/ComputedAccessibleNode.cpp index 8e6e85c..eb05eb7 100644 --- a/third_party/WebKit/Source/core/dom/ComputedAccessibleNode.cpp +++ b/third_party/WebKit/Source/core/dom/ComputedAccessibleNode.cpp
@@ -6,55 +6,123 @@ #include <stdint.h> +#include "bindings/core/v8/ScriptPromiseResolver.h" +#include "build/build_config.h" #include "core/dom/DOMException.h" +#include "core/frame/LocalFrame.h" #include "platform/bindings/ScriptState.h" -#include "third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolver.h" -#include "third_party/WebKit/Source/core/frame/LocalFrame.h" +#include "platform/scheduler/child/web_scheduler.h" +#include "platform/wtf/text/WTFString.h" +#include "public/platform/Platform.h" +#include "public/web/WebFrameClient.h" #include "third_party/WebKit/Source/core/frame/WebLocalFrameImpl.h" -#include "third_party/WebKit/Source/platform/wtf/text/WTFString.h" -#include "third_party/WebKit/public/web/WebFrameClient.h" namespace blink { -ComputedAccessibleNode* ComputedAccessibleNode::Create(Element* element) { - return new ComputedAccessibleNode(element); +namespace { +#if (defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)) +const double kIdleTaskStartTimeoutDelayMs = 1000.0; +#else +const double kIdleTaskStartTimeoutDelayMs = 4000.0; // For ChromeOS, Mobile +#endif } -ComputedAccessibleNode::ComputedAccessibleNode(Element* element) - : element_(element) { +ComputedAccessibleNodePromiseResolver* +ComputedAccessibleNodePromiseResolver::Create(ScriptState* script_state, + Element& element) { + return new ComputedAccessibleNodePromiseResolver(script_state, element); +} + +ComputedAccessibleNodePromiseResolver::ComputedAccessibleNodePromiseResolver( + ScriptState* script_state, + Element& element) + : idle_task_status_(kIdleTaskNotStarted), + element_(element), + resolver_(ScriptPromiseResolver::Create(script_state)), + context_(ExecutionContext::From(script_state)) {} + +ScriptPromise ComputedAccessibleNodePromiseResolver::Promise() { + return resolver_->Promise(); +} + +void ComputedAccessibleNodePromiseResolver::Trace(blink::Visitor* visitor) { + visitor->Trace(element_); + visitor->Trace(resolver_); + visitor->Trace(context_); +} + +void ComputedAccessibleNodePromiseResolver::ComputeAccessibleNode() { DCHECK(RuntimeEnabledFeatures::AccessibilityObjectModelEnabled()); - AXObjectCache* cache = element->GetDocument().GetOrCreateAXObjectCache(); - DCHECK(cache); - cache_ = cache; + DCHECK(Platform::Current()->CurrentThread()->Scheduler()); + idle_task_status_ = kIdleTaskNotStarted; + Platform::Current()->CurrentThread()->Scheduler()->PostIdleTask( + FROM_HERE, + WTF::Bind(&ComputedAccessibleNodePromiseResolver::IdleTaskFired, + WrapPersistent(this))); - LocalFrame* local_frame = element->ownerDocument()->GetFrame(); - WebFrameClient* client = WebLocalFrameImpl::FromFrame(local_frame)->Client(); - tree_ = client->GetOrCreateWebComputedAXTree(); + // We post the below task to check if the above idle task isn't late. + // There's no risk of concurrency as both tasks are on the same thread. + context_->GetTaskRunner(TaskType::kMiscPlatformAPI) + ->PostDelayedTask( + FROM_HERE, + WTF::Bind( + &ComputedAccessibleNodePromiseResolver::IdleTaskStartTimeoutEvent, + WrapPersistent(this)), + TimeDelta::FromMillisecondsD(kIdleTaskStartTimeoutDelayMs)); } +void ComputedAccessibleNodePromiseResolver::IdleTaskFired( + double deadline_seconds) { + UpdateTreeAndResolve(); +} + +void ComputedAccessibleNodePromiseResolver::UpdateTreeAndResolve() { + idle_task_status_ = kIdleTaskStarted; + Document& document = element_->GetDocument(); + document.View()->UpdateLifecycleToCompositingCleanPlusScrolling(); + AXObjectCache* cache = element_->GetDocument().GetOrCreateAXObjectCache(); + DCHECK(cache); + AXID ax_id = cache->GetAXID(element_); + + LocalFrame* local_frame = element_->ownerDocument()->GetFrame(); + WebFrameClient* client = WebLocalFrameImpl::FromFrame(local_frame)->Client(); + WebComputedAXTree* tree = client->GetOrCreateWebComputedAXTree(); + tree->ComputeAccessibilityTree(); + + ComputedAccessibleNode* accessible_node = + ComputedAccessibleNode::Create(ax_id, tree); + resolver_->Resolve(accessible_node); + idle_task_status_ = kIdleTaskCompleted; +} + +void ComputedAccessibleNodePromiseResolver::IdleTaskStartTimeoutEvent() { + if (idle_task_status_ != kIdleTaskNotStarted) + return; + + // If the idle task does not start after a delay threshold, just start it + // manually. + UpdateTreeAndResolve(); +} + +ComputedAccessibleNode* ComputedAccessibleNode::Create( + AXID ax_id, + WebComputedAXTree* tree) { + // TODO(meredithl): Change to GetOrCreate and check cache for existing node + // with this ID. + return new ComputedAccessibleNode(ax_id, tree); +} + +ComputedAccessibleNode::ComputedAccessibleNode(AXID ax_id, + WebComputedAXTree* tree) + : ax_id_(ax_id), tree_(tree) {} + ComputedAccessibleNode::~ComputedAccessibleNode() {} -ScriptPromise ComputedAccessibleNode::ComputeAccessibleProperties( - ScriptState* script_state) { - ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); - ScriptPromise promise = resolver->Promise(); - // TODO(meredithl): Post this task asynchronously, with a callback into - // this->OnSnapshotResponse. - if (!tree_->ComputeAccessibilityTree()) { - // TODO(meredithl): Change this exception to something relevant to AOM. - resolver->Reject(DOMException::Create(kUnknownError)); - } else { - OnSnapshotResponse(resolver); - } - - return promise; -} - int32_t ComputedAccessibleNode::GetIntAttribute(WebAOMIntAttribute attr, bool& is_null) const { int32_t out = 0; is_null = true; - if (tree_->GetIntAttributeForAXNode(cache_->GetAXID(element_), attr, &out)) { + if (tree_->GetIntAttributeForAXNode(ax_id_, attr, &out)) { is_null = false; } return out; @@ -63,8 +131,7 @@ const String ComputedAccessibleNode::GetStringAttribute( WebAOMStringAttribute attr) const { WebString out; - if (tree_->GetStringAttributeForAXNode(cache_->GetAXID(element_), attr, - &out)) { + if (tree_->GetStringAttributeForAXNode(ax_id_, attr, &out)) { return out; } return String(); @@ -81,7 +148,7 @@ } const String ComputedAccessibleNode::role() const { WebString out; - if (tree_->GetRoleForAXNode(cache_->GetAXID(element_), &out)) { + if (tree_->GetRoleForAXNode(ax_id_, &out)) { return out; } return String(); @@ -132,52 +199,44 @@ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_SET_SIZE, is_null); } -ComputedAccessibleNode* ComputedAccessibleNode::GetRelationFromCache( - AXID axid) const { - Element* element = cache_->GetElementFromAXID(axid); - if (!element) - return nullptr; - return element->GetComputedAccessibleNode(); -} - ComputedAccessibleNode* ComputedAccessibleNode::parent() const { - int32_t axid; - if (!tree_->GetParentIdForAXNode(cache_->GetAXID(element_), &axid)) { + int32_t parent_ax_id; + if (!tree_->GetParentIdForAXNode(ax_id_, &parent_ax_id)) { return nullptr; } - return GetRelationFromCache(axid); + return ComputedAccessibleNode::Create(parent_ax_id, tree_); } ComputedAccessibleNode* ComputedAccessibleNode::firstChild() const { - int32_t axid; - if (!tree_->GetFirstChildIdForAXNode(cache_->GetAXID(element_), &axid)) { + int32_t child_ax_id; + if (!tree_->GetFirstChildIdForAXNode(ax_id_, &child_ax_id)) { return nullptr; } - return GetRelationFromCache(axid); + return ComputedAccessibleNode::Create(child_ax_id, tree_); } ComputedAccessibleNode* ComputedAccessibleNode::lastChild() const { - int32_t axid; - if (!tree_->GetLastChildIdForAXNode(cache_->GetAXID(element_), &axid)) { + int32_t child_ax_id; + if (!tree_->GetLastChildIdForAXNode(ax_id_, &child_ax_id)) { return nullptr; } - return GetRelationFromCache(axid); + return ComputedAccessibleNode::Create(child_ax_id, tree_); } ComputedAccessibleNode* ComputedAccessibleNode::previousSibling() const { - int32_t axid; - if (!tree_->GetPreviousSiblingIdForAXNode(cache_->GetAXID(element_), &axid)) { + int32_t sibling_ax_id; + if (!tree_->GetPreviousSiblingIdForAXNode(ax_id_, &sibling_ax_id)) { return nullptr; } - return GetRelationFromCache(axid); + return ComputedAccessibleNode::Create(sibling_ax_id, tree_); } ComputedAccessibleNode* ComputedAccessibleNode::nextSibling() const { - int32_t axid; - if (!tree_->GetNextSiblingIdForAXNode(cache_->GetAXID(element_), &axid)) { + int32_t sibling_ax_id; + if (!tree_->GetNextSiblingIdForAXNode(ax_id_, &sibling_ax_id)) { return nullptr; } - return GetRelationFromCache(axid); + return ComputedAccessibleNode::Create(sibling_ax_id, tree_); } void ComputedAccessibleNode::OnSnapshotResponse( @@ -187,8 +246,6 @@ void ComputedAccessibleNode::Trace(Visitor* visitor) { ScriptWrappable::Trace(visitor); - visitor->Trace(element_); - visitor->Trace(cache_); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/ComputedAccessibleNode.h b/third_party/WebKit/Source/core/dom/ComputedAccessibleNode.h index 0b126eb..0d5631a 100644 --- a/third_party/WebKit/Source/core/dom/ComputedAccessibleNode.h +++ b/third_party/WebKit/Source/core/dom/ComputedAccessibleNode.h
@@ -18,11 +18,40 @@ class ScriptPromiseResolver; class ScriptState; +class ComputedAccessibleNodePromiseResolver final + : public GarbageCollectedFinalized<ComputedAccessibleNodePromiseResolver> { + public: + static ComputedAccessibleNodePromiseResolver* Create(ScriptState*, Element&); + + ScriptPromise Promise(); + + void ComputeAccessibleNode(); + + void Trace(blink::Visitor*); + + private: + ComputedAccessibleNodePromiseResolver(ScriptState*, Element&); + void IdleTaskFired(double deadline_seconds); + void UpdateTreeAndResolve(); + void IdleTaskStartTimeoutEvent(); + + enum IdleTaskStatus { + kIdleTaskNotStarted, + kIdleTaskStarted, + kIdleTaskCompleted, + }; + IdleTaskStatus idle_task_status_; + + Member<Element> element_; + Member<ScriptPromiseResolver> resolver_; + Member<ExecutionContext> context_; +}; + class ComputedAccessibleNode : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - static ComputedAccessibleNode* Create(Element*); + static ComputedAccessibleNode* Create(AXID, WebComputedAXTree*); virtual ~ComputedAccessibleNode(); void Trace(Visitor*); @@ -54,17 +83,15 @@ ComputedAccessibleNode* nextSibling() const; private: - explicit ComputedAccessibleNode(Element*); + explicit ComputedAccessibleNode(AXID, WebComputedAXTree*); // content::ComputedAXTree callback. void OnSnapshotResponse(ScriptPromiseResolver*); int32_t GetIntAttribute(WebAOMIntAttribute, bool& is_null) const; const String GetStringAttribute(WebAOMStringAttribute) const; - ComputedAccessibleNode* GetRelationFromCache(AXID) const; - Member<Element> element_; - Member<AXObjectCache> cache_; + AXID ax_id_; // This tree is owned by the RenderFrame. blink::WebComputedAXTree* tree_;
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index d978363..864b786 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -896,8 +896,8 @@ } // https://dom.spec.whatwg.org/#dom-document-createelement -Element* Document::createElement(const AtomicString& name, - ExceptionState& exception_state) { +Element* Document::CreateElementForBinding(const AtomicString& name, + ExceptionState& exception_state) { if (!IsValidElementName(this, name)) { exception_state.ThrowDOMException( kInvalidCharacterError, @@ -954,9 +954,10 @@ } // https://dom.spec.whatwg.org/#dom-document-createelement -Element* Document::createElement(const AtomicString& local_name, - const StringOrDictionary& string_or_options, - ExceptionState& exception_state) { +Element* Document::CreateElementForBinding( + const AtomicString& local_name, + const StringOrDictionary& string_or_options, + ExceptionState& exception_state) { // 1. If localName does not match Name production, throw InvalidCharacterError if (!IsValidElementName(this, local_name)) { exception_state.ThrowDOMException(
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index f831dabe..43dc85d1 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -328,6 +328,18 @@ Location* location() const; + Element* CreateElementForBinding(const AtomicString& local_name, + ExceptionState& = ASSERT_NO_EXCEPTION); + Element* CreateElementForBinding(const AtomicString& local_name, + const StringOrDictionary&, + ExceptionState&); + Element* createElementNS(const AtomicString& namespace_uri, + const AtomicString& qualified_name, + ExceptionState&); + Element* createElementNS(const AtomicString& namespace_uri, + const AtomicString& qualified_name, + const StringOrDictionary&, + ExceptionState&); DocumentFragment* createDocumentFragment(); Text* createTextNode(const String& data); Comment* createComment(const String& data); @@ -341,9 +353,6 @@ ExceptionState&, bool should_ignore_namespace_checks = false); Node* importNode(Node* imported_node, bool deep, ExceptionState&); - Element* createElementNS(const AtomicString& namespace_uri, - const AtomicString& qualified_name, - ExceptionState&); // "create an element" defined in DOM standard. This supports both of // autonomous custom elements and customized built-in elements. @@ -357,7 +366,8 @@ // However this is faster. Element* createElement(const QualifiedName&, const CreateElementFlags); // Creates an element without custom element processing. - Element* CreateRawElement(const QualifiedName&, const CreateElementFlags); + Element* CreateRawElement(const QualifiedName&, + const CreateElementFlags = CreateElementFlags()); Element* ElementFromPoint(double x, double y) const; HeapVector<Member<Element>> ElementsFromPoint(double x, double y) const; @@ -1193,15 +1203,6 @@ TextAutosizer* GetTextAutosizer(); - Element* createElement(const AtomicString& local_name, - ExceptionState& = ASSERT_NO_EXCEPTION); - Element* createElement(const AtomicString& local_name, - const StringOrDictionary&, - ExceptionState& = ASSERT_NO_EXCEPTION); - Element* createElementNS(const AtomicString& namespace_uri, - const AtomicString& qualified_name, - const StringOrDictionary&, - ExceptionState&); ScriptValue registerElement( ScriptState*, const AtomicString& name,
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl index 8d7019f..4b7253e5 100644 --- a/third_party/WebKit/Source/core/dom/Document.idl +++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -58,7 +58,7 @@ HTMLCollection getElementsByTagNameNS(DOMString? namespaceURI, DOMString localName); HTMLCollection getElementsByClassName(DOMString classNames); - [NewObject, DoNotTestNewObject, CustomElementCallbacks, PerWorldBindings, RaisesException] Element createElement(DOMString localName); + [NewObject, DoNotTestNewObject, CustomElementCallbacks, PerWorldBindings, RaisesException, ImplementedAs=CreateElementForBinding] Element createElement(DOMString localName); [NewObject, DoNotTestNewObject, CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName); [NewObject] DocumentFragment createDocumentFragment(); [NewObject] Text createTextNode(DOMString data); @@ -195,7 +195,7 @@ [CallWith=ScriptState, CustomElementCallbacks, RaisesException, MeasureAs=DocumentRegisterElement] CustomElementConstructor registerElement(DOMString type, optional ElementRegistrationOptions options); // https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-instantiate // FIXME: The typeExtension arguments should not be nullable. - [CustomElementCallbacks, PerWorldBindings, RaisesException] Element createElement(DOMString localName, (DOMString or Dictionary)? options); + [CustomElementCallbacks, PerWorldBindings, RaisesException, ImplementedAs=CreateElementForBinding] Element createElement(DOMString localName, (DOMString or Dictionary)? options); [CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName, (DOMString or Dictionary)? options); // Page Visibility
diff --git a/third_party/WebKit/Source/core/dom/DocumentTest.cpp b/third_party/WebKit/Source/core/dom/DocumentTest.cpp index 2368a49..35f9a13 100644 --- a/third_party/WebKit/Source/core/dom/DocumentTest.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentTest.cpp
@@ -613,13 +613,13 @@ EXPECT_EQ(GetDocument(), observer.LifecycleContext()); EXPECT_EQ(0, observer.CountContextDestroyedCalled()); - Element* div_node = GetDocument().createElement("div"); + Element* div_node = GetDocument().CreateRawElement(HTMLNames::divTag); GetDocument().body()->AppendChild(div_node); - Element* bold_node = GetDocument().createElement("b"); + Element* bold_node = GetDocument().CreateRawElement(HTMLNames::bTag); div_node->AppendChild(bold_node); - Element* italic_node = GetDocument().createElement("i"); + Element* italic_node = GetDocument().CreateRawElement(HTMLNames::iTag); div_node->AppendChild(italic_node); Node* text_node = GetDocument().createTextNode("0123456789"); @@ -679,7 +679,7 @@ TEST_F(DocumentTest, SynchronousMutationNotifierMoveTreeToNewDocument) { auto& observer = *new TestSynchronousMutationObserver(GetDocument()); - Node* move_sample = GetDocument().createElement("div"); + Node* move_sample = GetDocument().CreateRawElement(HTMLNames::divTag); move_sample->appendChild(GetDocument().createTextNode("a123")); move_sample->appendChild(GetDocument().createTextNode("b456")); GetDocument().body()->AppendChild(move_sample); @@ -703,7 +703,7 @@ auto& observer = *new TestSynchronousMutationObserver(GetDocument()); Element* const replaced_node = GetDocument().body(); GetDocument().documentElement()->ReplaceChild( - GetDocument().createElement("div"), GetDocument().body()); + GetDocument().CreateRawElement(HTMLNames::divTag), GetDocument().body()); ASSERT_EQ(2u, observer.ChildrenChangedNodes().size()); EXPECT_EQ(GetDocument().documentElement(), observer.ChildrenChangedNodes()[0]); @@ -813,9 +813,9 @@ // true. It's necessary to kick unload process. GetDocument().ImplicitOpen(kForceSynchronousParsing); GetDocument().CancelParsing(); - GetDocument().AppendChild(GetDocument().createElement("html")); + GetDocument().AppendChild(GetDocument().CreateRawElement(HTMLNames::htmlTag)); SetHtmlInnerHTML("<body><input required></body>"); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->setTextContent( "window.onunload = function() {" "document.querySelector('input').reportValidity(); };");
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index 13ddfc96..60fa62d8 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -1295,16 +1295,6 @@ return rare_data.EnsureAccessibleNode(this); } -ComputedAccessibleNode* Element::GetComputedAccessibleNode() { - if (!RuntimeEnabledFeatures::AccessibilityObjectModelEnabled()) - return nullptr; - - // TODO(meredithl): Create finer grain method for enabling accessibility. - GetDocument().GetPage()->GetSettings().SetAccessibilityEnabled(true); - ElementRareData& rare_data = EnsureElementRareData(); - return rare_data.EnsureComputedAccessibleNode(this); -} - const AtomicString& Element::getAttribute( const AtomicString& local_name) const { if (!GetElementData())
diff --git a/third_party/WebKit/Source/core/dom/Element.h b/third_party/WebKit/Source/core/dom/Element.h index 2edc6fa..d82bed81 100644 --- a/third_party/WebKit/Source/core/dom/Element.h +++ b/third_party/WebKit/Source/core/dom/Element.h
@@ -45,7 +45,6 @@ class AccessibleNode; class Attr; class Attribute; -class ComputedAccessibleNode; class CSSStyleDeclaration; class CustomElementDefinition; class DOMRect; @@ -296,8 +295,6 @@ AccessibleNode* ExistingAccessibleNode() const; AccessibleNode* accessibleNode(); - ComputedAccessibleNode* GetComputedAccessibleNode(); - void DidMoveToNewDocument(Document&) override; void removeAttribute(const AtomicString& name);
diff --git a/third_party/WebKit/Source/core/dom/ElementRareData.cpp b/third_party/WebKit/Source/core/dom/ElementRareData.cpp index ce97bf3..2ad1541 100644 --- a/third_party/WebKit/Source/core/dom/ElementRareData.cpp +++ b/third_party/WebKit/Source/core/dom/ElementRareData.cpp
@@ -78,14 +78,6 @@ computed_style_ = nullptr; } -ComputedAccessibleNode* ElementRareData::EnsureComputedAccessibleNode( - Element* owner_element) { - if (!computed_accessible_node_) { - computed_accessible_node_ = ComputedAccessibleNode::Create(owner_element); - } - return computed_accessible_node_; -} - AttrNodeList& ElementRareData::EnsureAttrNodeList() { if (!attr_node_list_) attr_node_list_ = new AttrNodeList;
diff --git a/third_party/WebKit/Source/core/dom/ElementRareData.h b/third_party/WebKit/Source/core/dom/ElementRareData.h index d5b83ccb..220f44d 100644 --- a/third_party/WebKit/Source/core/dom/ElementRareData.h +++ b/third_party/WebKit/Source/core/dom/ElementRareData.h
@@ -142,8 +142,6 @@ return accessible_node_; } - ComputedAccessibleNode* EnsureComputedAccessibleNode(Element* owner_element); - AttrNodeList& EnsureAttrNodeList(); AttrNodeList* GetAttrNodeList() { return attr_node_list_.Get(); } void RemoveAttrNodeList() { attr_node_list_.Clear(); }
diff --git a/third_party/WebKit/Source/core/dom/MutationObserverTest.cpp b/third_party/WebKit/Source/core/dom/MutationObserverTest.cpp index 6f386de8..419de5e 100644 --- a/third_party/WebKit/Source/core/dom/MutationObserverTest.cpp +++ b/third_party/WebKit/Source/core/dom/MutationObserverTest.cpp
@@ -35,7 +35,7 @@ TEST(MutationObserverTest, DisconnectCrash) { Persistent<Document> document = HTMLDocument::CreateForTest(); - HTMLElement* root = ToHTMLElement(document->createElement("html")); + auto* root = ToHTMLElement(document->CreateRawElement(HTMLNames::htmlTag)); document->AppendChild(root); root->SetInnerHTMLFromString("<head><title>\n</title></head><body></body>"); Node* head = root->firstChild()->firstChild();
diff --git a/third_party/WebKit/Source/core/dom/RangeTest.cpp b/third_party/WebKit/Source/core/dom/RangeTest.cpp index 70f8951..89607eb 100644 --- a/third_party/WebKit/Source/core/dom/RangeTest.cpp +++ b/third_party/WebKit/Source/core/dom/RangeTest.cpp
@@ -38,7 +38,8 @@ TEST_F(RangeTest, extractContentsWithDOMMutationEvent) { GetDocument().body()->SetInnerHTMLFromString("<span><b>abc</b>def</span>"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* const script_element = GetDocument().createElement("script"); + Element* const script_element = + GetDocument().CreateRawElement(HTMLNames::scriptTag); script_element->setTextContent( "let count = 0;" "const span = document.querySelector('span');" @@ -52,7 +53,7 @@ Element* const span_element = GetDocument().QuerySelector("span"); Range* const range = Range::Create(GetDocument(), span_element, 0, span_element, 1); - Element* const result = GetDocument().createElement("div"); + Element* const result = GetDocument().CreateRawElement(HTMLNames::divTag); result->AppendChild(range->extractContents(ASSERT_NO_EXCEPTION)); EXPECT_EQ("<b>abc</b>", result->InnerHTMLAsString()) @@ -171,8 +172,8 @@ } TEST_F(RangeTest, updateOwnerDocumentIfNeeded) { - Element* foo = GetDocument().createElement("foo"); - Element* bar = GetDocument().createElement("bar"); + Element* foo = GetDocument().CreateElementForBinding("foo"); + Element* bar = GetDocument().CreateElementForBinding("bar"); foo->AppendChild(bar); Range* range =
diff --git a/third_party/WebKit/Source/core/dom/ShadowDOMV0Test.cpp b/third_party/WebKit/Source/core/dom/ShadowDOMV0Test.cpp index 7afffc3..49a99c21 100644 --- a/third_party/WebKit/Source/core/dom/ShadowDOMV0Test.cpp +++ b/third_party/WebKit/Source/core/dom/ShadowDOMV0Test.cpp
@@ -35,8 +35,8 @@ TEST_F(ShadowDOMVTest, FeatureSetId) { LoadURL("about:blank"); - auto* host = GetDocument().createElement("div"); - auto* content = GetDocument().createElement("content"); + auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); + auto* content = GetDocument().CreateRawElement(HTMLNames::contentTag); content->setAttribute("select", "#foo"); host->CreateShadowRootInternal().AppendChild(content); EXPECT_TRUE(HasSelectorForIdInShadow(host, "foo")); @@ -52,8 +52,8 @@ TEST_F(ShadowDOMVTest, FeatureSetClassName) { LoadURL("about:blank"); - auto* host = GetDocument().createElement("div"); - auto* content = GetDocument().createElement("content"); + auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); + auto* content = GetDocument().CreateRawElement(HTMLNames::contentTag); content->setAttribute("select", ".foo"); host->CreateShadowRootInternal().AppendChild(content); EXPECT_TRUE(HasSelectorForClassInShadow(host, "foo")); @@ -69,8 +69,8 @@ TEST_F(ShadowDOMVTest, FeatureSetAttributeName) { LoadURL("about:blank"); - auto* host = GetDocument().createElement("div"); - auto* content = GetDocument().createElement("content"); + auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); + auto* content = GetDocument().CreateRawElement(HTMLNames::contentTag); content->setAttribute("select", "div[foo]"); host->CreateShadowRootInternal().AppendChild(content); EXPECT_TRUE(HasSelectorForAttributeInShadow(host, "foo")); @@ -86,8 +86,8 @@ TEST_F(ShadowDOMVTest, FeatureSetMultipleSelectors) { LoadURL("about:blank"); - auto* host = GetDocument().createElement("div"); - auto* content = GetDocument().createElement("content"); + auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); + auto* content = GetDocument().CreateRawElement(HTMLNames::contentTag); content->setAttribute("select", "#foo,.bar,div[baz]"); host->CreateShadowRootInternal().AppendChild(content); EXPECT_TRUE(HasSelectorForIdInShadow(host, "foo")); @@ -103,7 +103,7 @@ TEST_F(ShadowDOMVTest, FeatureSetSubtree) { LoadURL("about:blank"); - auto* host = GetDocument().createElement("div"); + auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); host->CreateShadowRootInternal().SetInnerHTMLFromString(R"HTML( <div> <div></div> @@ -121,12 +121,12 @@ TEST_F(ShadowDOMVTest, FeatureSetMultipleShadowRoots) { LoadURL("about:blank"); - auto* host = GetDocument().createElement("div"); + auto* host = GetDocument().CreateRawElement(HTMLNames::divTag); auto& host_shadow = host->CreateShadowRootInternal(); host_shadow.SetInnerHTMLFromString("<content select='#foo'></content>"); - auto* child = GetDocument().createElement("div"); + auto* child = GetDocument().CreateRawElement(HTMLNames::divTag); auto& child_root = child->CreateShadowRootInternal(); - auto* child_content = GetDocument().createElement("content"); + auto* child_content = GetDocument().CreateRawElement(HTMLNames::contentTag); child_content->setAttribute("select", "#bar"); child_root.AppendChild(child_content); host_shadow.AppendChild(child);
diff --git a/third_party/WebKit/Source/core/dom/TreeScopeAdopterTest.cpp b/third_party/WebKit/Source/core/dom/TreeScopeAdopterTest.cpp index ba54cc0..a8d8af2 100644 --- a/third_party/WebKit/Source/core/dom/TreeScopeAdopterTest.cpp +++ b/third_party/WebKit/Source/core/dom/TreeScopeAdopterTest.cpp
@@ -15,14 +15,14 @@ Document* doc1 = Document::CreateForTest(); Document* doc2 = Document::CreateForTest(); - Element* html1 = doc1->createElement("html"); + Element* html1 = doc1->CreateRawElement(HTMLNames::htmlTag); doc1->AppendChild(html1); - Element* div1 = doc1->createElement("div"); + Element* div1 = doc1->CreateRawElement(HTMLNames::divTag); html1->AppendChild(div1); - Element* html2 = doc2->createElement("html"); + Element* html2 = doc2->CreateRawElement(HTMLNames::htmlTag); doc2->AppendChild(html2); - Element* div2 = doc1->createElement("div"); + Element* div2 = doc1->CreateRawElement(HTMLNames::divTag); html2->AppendChild(div2); EXPECT_EQ(div1->ownerDocument(), doc1); @@ -43,9 +43,9 @@ Document* doc1 = Document::CreateForTest(); Document* doc2 = Document::CreateForTest(); - Element* html1 = doc1->createElement("html"); + Element* html1 = doc1->CreateRawElement(HTMLNames::htmlTag); doc1->AppendChild(html1); - Element* div1 = doc1->createElement("div"); + Element* div1 = doc1->CreateRawElement(HTMLNames::divTag); html1->AppendChild(div1); EXPECT_EQ(doc1->GetShadowCascadeOrder(), ShadowCascadeOrder::kShadowCascadeNone); @@ -54,9 +54,9 @@ ShadowCascadeOrder::kShadowCascadeV0); EXPECT_TRUE(doc1->MayContainV0Shadow()); - Element* html2 = doc2->createElement("html"); + Element* html2 = doc2->CreateRawElement(HTMLNames::htmlTag); doc2->AppendChild(html2); - Element* div2 = doc1->createElement("div"); + Element* div2 = doc1->CreateRawElement(HTMLNames::divTag); html2->AppendChild(div2); div2->AttachShadowRootInternal(ShadowRootType::kOpen); @@ -79,9 +79,9 @@ Document* doc1 = Document::CreateForTest(); Document* doc2 = Document::CreateForTest(); - Element* html1 = doc1->createElement("html"); + Element* html1 = doc1->CreateRawElement(HTMLNames::htmlTag); doc1->AppendChild(html1); - Element* div1 = doc1->createElement("div"); + Element* div1 = doc1->CreateRawElement(HTMLNames::divTag); html1->AppendChild(div1); EXPECT_EQ(doc1->GetShadowCascadeOrder(), ShadowCascadeOrder::kShadowCascadeNone); @@ -90,9 +90,9 @@ ShadowCascadeOrder::kShadowCascadeV1); EXPECT_FALSE(doc1->MayContainV0Shadow()); - Element* html2 = doc2->createElement("html"); + Element* html2 = doc2->CreateRawElement(HTMLNames::htmlTag); doc2->AppendChild(html2); - Element* div2 = doc1->createElement("div"); + Element* div2 = doc1->CreateRawElement(HTMLNames::divTag); html2->AppendChild(div2); div2->CreateShadowRootInternal();
diff --git a/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp b/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp index 818097d..fc38f43 100644 --- a/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp +++ b/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp
@@ -4,7 +4,6 @@ #include "core/dom/TreeScope.h" -#include "bindings/core/v8/string_or_dictionary.h" #include "core/dom/Document.h" #include "core/dom/Element.h" #include "core/dom/ShadowRoot.h" @@ -16,7 +15,7 @@ Document* document = Document::CreateForTest(); EXPECT_EQ(document, document->CommonAncestorTreeScope(*document)); - Element* html = document->createElement("html", StringOrDictionary()); + Element* html = document->CreateRawElement(HTMLNames::htmlTag); document->AppendChild(html); ShadowRoot& shadow_root = html->CreateShadowRootInternal(); EXPECT_EQ(shadow_root, shadow_root.CommonAncestorTreeScope(shadow_root)); @@ -28,7 +27,7 @@ // shadowRoot Document* document = Document::CreateForTest(); - Element* html = document->createElement("html", StringOrDictionary()); + Element* html = document->CreateRawElement(HTMLNames::htmlTag); document->AppendChild(html); ShadowRoot& shadow_root = html->CreateShadowRootInternal(); @@ -42,11 +41,11 @@ // A B Document* document = Document::CreateForTest(); - Element* html = document->createElement("html", StringOrDictionary()); + Element* html = document->CreateRawElement(HTMLNames::htmlTag); document->AppendChild(html); - Element* head = document->createElement("head", StringOrDictionary()); + Element* head = document->CreateRawElement(HTMLNames::headTag); html->AppendChild(head); - Element* body = document->createElement("body", StringOrDictionary()); + Element* body = document->CreateRawElement(HTMLNames::bodyTag); html->AppendChild(body); ShadowRoot& shadow_root_a = head->CreateShadowRootInternal(); @@ -64,17 +63,17 @@ // A Document* document = Document::CreateForTest(); - Element* html = document->createElement("html", StringOrDictionary()); + Element* html = document->CreateRawElement(HTMLNames::htmlTag); document->AppendChild(html); - Element* head = document->createElement("head", StringOrDictionary()); + Element* head = document->CreateRawElement(HTMLNames::headTag); html->AppendChild(head); - Element* body = document->createElement("body", StringOrDictionary()); + Element* body = document->CreateRawElement(HTMLNames::bodyTag); html->AppendChild(body); ShadowRoot& shadow_root_y = head->CreateShadowRootInternal(); ShadowRoot& shadow_root_b = body->CreateShadowRootInternal(); - Element* div_in_y = document->createElement("div", StringOrDictionary()); + Element* div_in_y = document->CreateRawElement(HTMLNames::divTag); shadow_root_y.AppendChild(div_in_y); ShadowRoot& shadow_root_a = div_in_y->CreateShadowRootInternal();
diff --git a/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp b/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp index 9c95a0ed..b63c03a 100644 --- a/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp +++ b/third_party/WebKit/Source/core/editing/CaretDisplayItemClientTest.cpp
@@ -60,7 +60,7 @@ } Element* AppendBlock(const String& data) { - Element* block = GetDocument().createElement("div"); + Element* block = GetDocument().CreateRawElement(HTMLNames::divTag); Text* text = GetDocument().createTextNode(data); block->AppendChild(text); GetDocument().body()->AppendChild(block);
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp b/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp index 0b0e855..cc759c48 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp
@@ -110,7 +110,7 @@ // However, |setBodyContent()| automatically creates HTML, HEAD and BODY // element. So, we build DOM tree manually. // Note: This is unusual HTML taken from http://crbug.com/574230 - Element* table = GetDocument().createElement("table"); + Element* table = GetDocument().CreateRawElement(HTMLNames::tableTag); table->SetInnerHTMLFromString("<caption>foo</caption>"); while (GetDocument().firstChild()) GetDocument().firstChild()->remove();
diff --git a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp index 31101a0..ff35cfb 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp +++ b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp
@@ -292,7 +292,7 @@ } TEST_F(FrameSelectionTest, SelectAllWithUnselectableRoot) { - Element* select = GetDocument().createElement("select"); + Element* select = GetDocument().CreateRawElement(HTMLNames::selectTag); GetDocument().ReplaceChild(select, GetDocument().documentElement()); GetDocument().UpdateStyleAndLayout(); Selection().SelectAll();
diff --git a/third_party/WebKit/Source/core/editing/SelectionControllerTest.cpp b/third_party/WebKit/Source/core/editing/SelectionControllerTest.cpp index a5411b7..e461bd7d 100644 --- a/third_party/WebKit/Source/core/editing/SelectionControllerTest.cpp +++ b/third_party/WebKit/Source/core/editing/SelectionControllerTest.cpp
@@ -110,7 +110,7 @@ const char* body_content = "<div id='sample' contenteditable>sample</div>"; SetBodyContent(body_content); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "var sample = document.getElementById('sample');" "sample.addEventListener('onselectstart', " @@ -142,7 +142,7 @@ TEST_F(SelectionControllerTest, SetCaretAtHitTestResultWithDisconnectedPosition) { GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.designMode = 'on';" "const selection = window.getSelection();"
diff --git a/third_party/WebKit/Source/core/editing/VisiblePositionTest.cpp b/third_party/WebKit/Source/core/editing/VisiblePositionTest.cpp index b8bd4a8b..ff27cef 100644 --- a/third_party/WebKit/Source/core/editing/VisiblePositionTest.cpp +++ b/third_party/WebKit/Source/core/editing/VisiblePositionTest.cpp
@@ -69,7 +69,7 @@ VisiblePosition null_visible_position; VisiblePosition non_null_visible_position = CreateVisiblePosition(position); - Element* div = GetDocument().createElement("div"); + Element* div = GetDocument().CreateRawElement(HTMLNames::divTag); GetDocument().body()->AppendChild(div); EXPECT_TRUE(null_visible_position.IsValid());
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp index 536b790..e3bed045 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp
@@ -126,7 +126,7 @@ Node* two = GetDocument().QuerySelector("#two"); Node* three = GetDocument().QuerySelector("#three"); Node* four = GetDocument().QuerySelector("#four"); - Element* html = GetDocument().createElement("html"); + Element* html = GetDocument().CreateRawElement(HTMLNames::htmlTag); // Move two, three and four into second html element. html->AppendChild(two); html->AppendChild(three); @@ -897,7 +897,7 @@ Node* two = GetDocument().QuerySelector("#two"); Node* three = GetDocument().QuerySelector("#three"); Node* four = GetDocument().QuerySelector("#four"); - Element* html = GetDocument().createElement("html"); + Element* html = GetDocument().CreateRawElement(HTMLNames::htmlTag); // Move two, three and four into second html element. html->AppendChild(two); html->AppendChild(three);
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertTextCommandTest.cpp b/third_party/WebKit/Source/core/editing/commands/InsertTextCommandTest.cpp index 141a252..ad889f5 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertTextCommandTest.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertTextCommandTest.cpp
@@ -256,8 +256,8 @@ // Since the HTML parser rejects it as there are nested <a> elements. // We are contructing the remaining DOM manually. Element* const anchor = GetDocument().QuerySelector("a"); - Element* nested_anchor = GetDocument().createElement("a"); - Element* iElement = GetDocument().createElement("i"); + Element* nested_anchor = GetDocument().CreateRawElement(HTMLNames::aTag); + Element* iElement = GetDocument().CreateRawElement(HTMLNames::iTag); nested_anchor->setAttribute("href", "www"); iElement->SetInnerHTMLFromString("home");
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommandTest.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommandTest.cpp index 2709a95..197eef3 100644 --- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommandTest.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommandTest.cpp
@@ -39,7 +39,7 @@ .Build()); DocumentFragment* fragment = GetDocument().createDocumentFragment(); - fragment->AppendChild(GetDocument().createElement("span")); + fragment->AppendChild(GetDocument().CreateRawElement(HTMLNames::spanTag)); // |options| are taken from |Editor::replaceSelectionWithFragment()| with // |selectReplacement| and |smartReplace|.
diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommandTest.cpp b/third_party/WebKit/Source/core/editing/commands/TypingCommandTest.cpp index 321a884..1859995 100644 --- a/third_party/WebKit/Source/core/editing/commands/TypingCommandTest.cpp +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommandTest.cpp
@@ -27,15 +27,15 @@ SetBodyContent("<div contenteditable></div>"); // <input><form></form></input> - Element* input1 = GetDocument().createElement("input"); - Element* form = GetDocument().createElement("form"); + Element* input1 = GetDocument().CreateRawElement(HTMLNames::inputTag); + Element* form = GetDocument().CreateRawElement(HTMLNames::formTag); input1->AppendChild(form); // <tr><input><header></header></input><rbc></rbc></tr> - Element* tr = GetDocument().createElement("tr"); - Element* input2 = GetDocument().createElement("input"); - Element* header = GetDocument().createElement("header"); - Element* rbc = GetDocument().createElement("rbc"); + Element* tr = GetDocument().CreateRawElement(HTMLNames::trTag); + Element* input2 = GetDocument().CreateRawElement(HTMLNames::inputTag); + Element* header = GetDocument().CreateRawElement(HTMLNames::headerTag); + Element* rbc = GetDocument().CreateElementForBinding("rbc"); input2->AppendChild(header); tr->AppendChild(input2); tr->AppendChild(rbc);
diff --git a/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp b/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp index d3406cc..a55c2d0e 100644 --- a/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp +++ b/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp
@@ -53,7 +53,7 @@ GetDocument().GetSettings()->SetScriptEnabled(true); Element* editable = InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('beforeinput', " " event => document.title = `beforeinput.data:${event.data};`);" @@ -71,7 +71,7 @@ GetDocument().GetSettings()->SetScriptEnabled(true); Element* editable = InsertHTMLElement("<div id='sample' contentEditable></div>", "sample"); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); switch (type) { case kNoSelection: @@ -1168,7 +1168,7 @@ GetDocument().GetSettings()->SetScriptEnabled(true); Element* editable = InsertHTMLElement("<div id='sample' contenteditable></div>", "sample"); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('beforeinput', " " event => document.title = " @@ -2525,7 +2525,7 @@ InsertHTMLElement("<div id='sample' contenteditable>hello</div>", "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2560,7 +2560,7 @@ "<div id='sample' contenteditable>hello world</div>", "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2598,7 +2598,7 @@ "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2631,7 +2631,7 @@ "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2665,7 +2665,7 @@ "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2699,7 +2699,7 @@ "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2732,7 +2732,7 @@ "<div id='sample' contenteditable>hello world</div>", "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2769,7 +2769,7 @@ InsertHTMLElement("<div id='sample' contenteditable>hello</div>", "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('compositionend', " " event => {" @@ -2805,7 +2805,7 @@ "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('compositionend', " " event => {" @@ -2839,7 +2839,7 @@ "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('compositionend', " " event => {" @@ -2872,7 +2872,7 @@ "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('compositionend', " " event => {" @@ -2904,7 +2904,7 @@ "sample"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('compositionend', " " event => {" @@ -2936,7 +2936,7 @@ InsertHTMLElement("<input id='sample' maxlength='2'>", "sample")); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2966,7 +2966,7 @@ InsertHTMLElement("<input id='sample' maxlength='2'>", "sample")); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('input', " " event => {" @@ -2996,7 +2996,7 @@ InsertHTMLElement("<input id='sample' maxlength='2'>", "sample")); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('compositionend', " " event => {" @@ -3028,7 +3028,7 @@ InsertHTMLElement("<input id='sample' maxlength='2'>", "sample")); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.getElementById('sample').addEventListener('compositionend', " " event => {"
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTest.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTest.cpp index e556672..3e04a417 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTest.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTest.cpp
@@ -1015,7 +1015,7 @@ TextControlElement* input_element = ToTextControlElement(GetDocument().getElementById("a")); Element* inner_editor = input_element->InnerEditorElement(); - Element* br = GetDocument().createElement("br"); + Element* br = GetDocument().CreateRawElement(HTMLNames::brTag); inner_editor->AppendChild(br); const ShadowRoot* shadow_root = input_element->UserAgentShadowRoot(); const Position start = Position::FirstPositionInNode(*shadow_root);
diff --git a/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp b/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp index 65aed03..8e291d2 100644 --- a/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp +++ b/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp
@@ -241,7 +241,7 @@ } TEST_F(SelectionSampleTest, SerializeVoidElementBR) { - Element* const br = GetDocument().createElement("br"); + Element* const br = GetDocument().CreateRawElement(HTMLNames::brTag); br->appendChild(GetDocument().createTextNode("abc")); GetDocument().body()->appendChild(br); EXPECT_EQ(
diff --git a/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.cpp index c7fe67c6..b2c73d35 100644 --- a/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.cpp
@@ -451,12 +451,9 @@ inspector_session_->Append( InspectorApplicationCacheAgent::Create(inspected_frames)); - InspectorWorkerAgent* worker_agent = - new InspectorWorkerAgent(inspected_frames); - inspector_session_->Append(worker_agent); + inspector_session_->Append(new InspectorWorkerAgent(inspected_frames)); - tracing_agent_ = - InspectorTracingAgent::Create(agent_, worker_agent, inspected_frames); + tracing_agent_ = new InspectorTracingAgent(agent_, inspected_frames); inspector_session_->Append(tracing_agent_); page_agent_ = InspectorPageAgent::Create(
diff --git a/third_party/WebKit/Source/core/exported/WebViewTest.cpp b/third_party/WebKit/Source/core/exported/WebViewTest.cpp index e1bdb2a..3ce8efa5 100644 --- a/third_party/WebKit/Source/core/exported/WebViewTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebViewTest.cpp
@@ -1013,7 +1013,7 @@ // Do arbitrary change to make layout dirty. Document& document = *web_view->MainFrameImpl()->GetFrame()->GetDocument(); - Element* br = document.createElement("br"); + Element* br = document.CreateRawElement(HTMLNames::brTag); document.body()->AppendChild(br); // Should not hit assertion when calling
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp index 650e4c6..3a928cc 100644 --- a/third_party/WebKit/Source/core/frame/Deprecation.cpp +++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -173,15 +173,6 @@ function, milestoneString(milestone), allow_string); } -String DeprecatedWebAudioValueSetterBehavior() { - return String::Format( - "AudioParam value setter will become equivalent to " - "AudioParam.setValueAtTime() in %s " - "See https://webaudio.github.io/web-audio-api/#dom-audioparam-value for " - "more details.", - milestoneString(M65)); -} - DeprecationInfo GetDeprecationInfo(WebFeature feature) { switch (feature) { // Quota @@ -546,10 +537,6 @@ "HTMLMediaElement.srcObject", M68, "5618491470118912")}; - case WebFeature::kWebAudioValueSetterIsSetValue: - return {"WebAudioValueSetterIsSetValue", Unknown, - DeprecatedWebAudioValueSetterBehavior()}; - case WebFeature::kChromeLoadTimesRequestTime: case WebFeature::kChromeLoadTimesStartLoadTime: case WebFeature::kChromeLoadTimesCommitLoadTime:
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp index 2f47c6fd..dabaea2 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -1109,9 +1109,12 @@ ScriptState* script_state, Element* element) { DCHECK(element); - ComputedAccessibleNode* computed_accessible_node = - element->GetComputedAccessibleNode(); - return computed_accessible_node->ComputeAccessibleProperties(script_state); + // TODO(meredithl): Create finer grain method for enabling accessibility. + element->GetDocument().GetPage()->GetSettings().SetAccessibilityEnabled(true); + ComputedAccessibleNodePromiseResolver* resolver = + ComputedAccessibleNodePromiseResolver::Create(script_state, *element); + resolver->ComputeAccessibleNode(); + return resolver->Promise(); } CSSRuleList* LocalDOMWindow::getMatchedCSSRules(
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp index a57f3bf..a029ddc0 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -4617,11 +4617,14 @@ ScrollableArea* LocalFrameView::ScrollableAreaWithElementId( const CompositorElementId& id) { - // With root layer scrolling the LocalFrameView does not scroll. - if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled() && - id == GetCompositorElementId()) { - return this; - } + // Check for the layout viewport, which may not be in scrollable_areas_ if it + // is styled overflow: hidden. (Other overflow: hidden elements won't have + // composited scrolling layers per crbug.com/784053, so we don't have to worry + // about them.) + ScrollableArea* viewport = LayoutViewportScrollableArea(); + if (id == viewport->GetCompositorElementId()) + return viewport; + if (scrollable_areas_) { // This requires iterating over all scrollable areas. We may want to store a // map of ElementId to ScrollableArea if this is an issue for performance.
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index 4050867..b9bd9d48 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -1266,6 +1266,8 @@ context_ = kDisabledContext; else if (!frame->Client() || !frame->Client()->ShouldTrackUseCounter(url)) context_ = kDisabledContext; + else if (frame->GetDocument()->IsPrefetchOnly()) + context_ = kDisabledContext; else if (SchemeRegistry::ShouldTrackUsageMetricsForScheme(url.Protocol())) context_ = kDefaultContext; else
diff --git a/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp b/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp index 9bb3dc5b..3821a35 100644 --- a/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
@@ -31,6 +31,7 @@ #include "core/html_names.h" #include "core/inspector/ConsoleMessage.h" #include "core/layout/LayoutIFrame.h" +#include "core/page/Page.h" #include "core/policy/IFramePolicy.h" #include "platform/runtime_enabled_features.h" @@ -207,6 +208,24 @@ } } } else { + // Websites picked up a Chromium article that used this non-specified + // attribute which ended up changing shape after the specification process. + // This error message and use count will help developers to move to the + // proper solution. + // To avoid polluting the console, this is being recorded only once per + // page. + if (name == "gesture" && value == "media" && GetDocument().GetPage() && + !GetDocument().GetPage()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kHTMLIFrameElementGestureMedia)) { + UseCounter::Count(GetDocument(), + WebFeature::kHTMLIFrameElementGestureMedia); + GetDocument().AddConsoleMessage( + ConsoleMessage::Create(kOtherMessageSource, kWarningMessageLevel, + "<iframe gesture=\"media\"> is not supported. " + "Use <iframe allow=\"autoplay\">, " + "https://goo.gl/ximf56")); + } + if (name == srcAttr) LogUpdateAttributeIfIsolatedWorldAndInDocument("iframe", params); HTMLFrameElementBase::ParseAttribute(params);
diff --git a/third_party/WebKit/Source/core/html/custom/CustomElementTest.cpp b/third_party/WebKit/Source/core/html/custom/CustomElementTest.cpp index 78bc6345..ac12e74 100644 --- a/third_party/WebKit/Source/core/html/custom/CustomElementTest.cpp +++ b/third_party/WebKit/Source/core/html/custom/CustomElementTest.cpp
@@ -185,7 +185,7 @@ std::unique_ptr<DummyPageHolder> page_holder = DummyPageHolder::Create(); Document& document = page_holder->GetDocument(); for (const auto& data : create_element_data) { - Element* element = document.createElement(data.name); + Element* element = document.CreateElementForBinding(data.name); EXPECT_EQ(data.state, element->GetCustomElementState()) << data.name; EXPECT_EQ(data.v0state, element->GetV0CustomElementState()) << data.name; @@ -224,7 +224,7 @@ Document& document = holder->GetDocument(); EXPECT_TRUE(document.IsHTMLDocument()) << "this test requires a HTML document"; - Element* element = document.createElement("A-A", should_not_throw); + Element* element = document.CreateElementForBinding("A-A", should_not_throw); EXPECT_EQ(definition, element->GetCustomElementDefinition()); }
diff --git a/third_party/WebKit/Source/core/html/custom/CustomElementUpgradeSorterTest.cpp b/third_party/WebKit/Source/core/html/custom/CustomElementUpgradeSorterTest.cpp index 2331d5c3..638bc24 100644 --- a/third_party/WebKit/Source/core/html/custom/CustomElementUpgradeSorterTest.cpp +++ b/third_party/WebKit/Source/core/html/custom/CustomElementUpgradeSorterTest.cpp
@@ -27,7 +27,7 @@ Element* CreateElementWithId(const char* local_name, const char* id) { NonThrowableExceptionState no_exceptions; - Element* element = GetDocument().createElement( + Element* element = GetDocument().CreateElementForBinding( local_name, StringOrDictionary(), no_exceptions); element->setAttribute(HTMLNames::idAttr, id); return element; @@ -48,8 +48,8 @@ TEST_F(CustomElementUpgradeSorterTest, inOtherDocument_notInSet) { NonThrowableExceptionState no_exceptions; - Element* element = - GetDocument().createElement("a-a", StringOrDictionary(), no_exceptions); + Element* element = GetDocument().CreateElementForBinding( + "a-a", StringOrDictionary(), no_exceptions); Document* other_document = HTMLDocument::CreateForTest(); other_document->AppendChild(element); @@ -67,8 +67,8 @@ TEST_F(CustomElementUpgradeSorterTest, oneCandidate) { NonThrowableExceptionState no_exceptions; - Element* element = - GetDocument().createElement("a-a", StringOrDictionary(), no_exceptions); + Element* element = GetDocument().CreateElementForBinding( + "a-a", StringOrDictionary(), no_exceptions); GetDocument().documentElement()->AppendChild(element); CustomElementUpgradeSorter sorter;
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementTest.cpp b/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementTest.cpp index fcd7693..5aa5c2d 100644 --- a/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementTest.cpp +++ b/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementTest.cpp
@@ -135,7 +135,7 @@ GetDocument().documentElement()->SetInnerHTMLFromString("<select></select>"); HTMLFormControlElement* const select = ToHTMLFormControlElement(GetDocument().QuerySelector("select")); - Element* const optgroup = GetDocument().createElement("optgroup"); + auto* const optgroup = GetDocument().CreateRawElement(HTMLNames::optgroupTag); auto* validation_client = new MockFormValidationMessageClient(); GetDocument().GetPage()->SetValidationMessageClient(validation_client);
diff --git a/third_party/WebKit/Source/core/html/forms/OptionListTest.cpp b/third_party/WebKit/Source/core/html/forms/OptionListTest.cpp index ec191a3..7f44110 100644 --- a/third_party/WebKit/Source/core/html/forms/OptionListTest.cpp +++ b/third_party/WebKit/Source/core/html/forms/OptionListTest.cpp
@@ -43,7 +43,8 @@ Select().SetInnerHTMLFromString( "text<input><option id=o1></option><input><option " "id=o2></option><input>"); - HTMLElement* div = ToHTMLElement(Select().GetDocument().createElement("div")); + auto* div = + ToHTMLElement(Select().GetDocument().CreateRawElement(HTMLNames::divTag)); div->SetInnerHTMLFromString("<option id=o3></option>"); Select().AppendChild(div); OptionList list = Select().GetOptionList();
diff --git a/third_party/WebKit/Source/core/html/media/HTMLVideoElementPersistentTest.cpp b/third_party/WebKit/Source/core/html/media/HTMLVideoElementPersistentTest.cpp index 38da1ad..33ff9b9 100644 --- a/third_party/WebKit/Source/core/html/media/HTMLVideoElementPersistentTest.cpp +++ b/third_party/WebKit/Source/core/html/media/HTMLVideoElementPersistentTest.cpp
@@ -282,7 +282,7 @@ EXPECT_EQ(FullscreenElement(), nullptr); // Inserting a <span> between the <div> and <video>. - Persistent<Element> span = GetDocument().createElement("span"); + Persistent<Element> span = GetDocument().CreateRawElement(HTMLNames::spanTag); DivElement()->AppendChild(span); span->AppendChild(VideoElement());
diff --git a/third_party/WebKit/Source/core/html/media/MediaCustomControlsFullscreenDetectorTest.cpp b/third_party/WebKit/Source/core/html/media/MediaCustomControlsFullscreenDetectorTest.cpp index 156909f..2a6d01a 100644 --- a/third_party/WebKit/Source/core/html/media/MediaCustomControlsFullscreenDetectorTest.cpp +++ b/third_party/WebKit/Source/core/html/media/MediaCustomControlsFullscreenDetectorTest.cpp
@@ -112,8 +112,8 @@ TEST_F(MediaCustomControlsFullscreenDetectorTest, hasNoListenersBeforeAddingToDocument) { - HTMLVideoElement* video = - ToHTMLVideoElement(GetDocument().createElement("video")); + auto* video = + ToHTMLVideoElement(GetDocument().CreateRawElement(HTMLNames::videoTag)); EXPECT_FALSE(CheckEventListenerRegistered(GetDocument(), EventTypeNames::fullscreenchange, @@ -127,8 +127,8 @@ TEST_F(MediaCustomControlsFullscreenDetectorTest, hasListenersAfterAddToDocumentByScript) { - HTMLVideoElement* video = - ToHTMLVideoElement(GetDocument().createElement("video")); + auto* video = + ToHTMLVideoElement(GetDocument().CreateRawElement(HTMLNames::videoTag)); GetDocument().body()->AppendChild(video); EXPECT_TRUE(CheckEventListenerRegistered( @@ -155,8 +155,8 @@ TEST_F(MediaCustomControlsFullscreenDetectorTest, hasListenersAfterDocumentMove) { - HTMLVideoElement* video = - ToHTMLVideoElement(GetDocument().createElement("video")); + auto* video = + ToHTMLVideoElement(GetDocument().CreateRawElement(HTMLNames::videoTag)); GetDocument().body()->AppendChild(video); NewDocument().body()->AppendChild(VideoElement());
diff --git a/third_party/WebKit/Source/core/input/EventHandlerTest.cpp b/third_party/WebKit/Source/core/input/EventHandlerTest.cpp index 3ebc37c..9b7f1055 100644 --- a/third_party/WebKit/Source/core/input/EventHandlerTest.cpp +++ b/third_party/WebKit/Source/core/input/EventHandlerTest.cpp
@@ -561,7 +561,7 @@ "<style>*:hover { color: red; }</style>" "<div>foo</div>"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.addEventListener('contextmenu', event => " "event.preventDefault());"); @@ -990,7 +990,7 @@ TEST_F(EventHandlerNavigationTest, MouseButtonsDontNavigate) { SetHtmlInnerHTML("<div>"); GetDocument().GetSettings()->SetScriptEnabled(true); - Element* script = GetDocument().createElement("script"); + Element* script = GetDocument().CreateRawElement(HTMLNames::scriptTag); script->SetInnerHTMLFromString( "document.addEventListener('mouseup', event => " "event.preventDefault());");
diff --git a/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp b/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp index 4065694e..ac90bd5 100644 --- a/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp +++ b/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp
@@ -8,6 +8,7 @@ #include "core/dom/Node.h" #include "core/frame/LocalFrame.h" #include "core/inspector/IdentifiersFactory.h" +#include "core/workers/WorkerThread.h" #include "platform/wtf/Assertions.h" #include "platform/wtf/Time.h" #include "public/web/WebConsoleMessage.h" @@ -51,10 +52,11 @@ MessageLevel level, const String& message, std::unique_ptr<SourceLocation> location, - const String& worker_id) { + WorkerThread* worker_thread) { ConsoleMessage* console_message = ConsoleMessage::Create( kWorkerMessageSource, level, message, std::move(location)); - console_message->worker_id_ = worker_id; + console_message->worker_id_ = + IdentifiersFactory::IdFromToken(worker_thread->GetDevToolsWorkerToken()); return console_message; }
diff --git a/third_party/WebKit/Source/core/inspector/ConsoleMessage.h b/third_party/WebKit/Source/core/inspector/ConsoleMessage.h index b2457b7..07a35929 100644 --- a/third_party/WebKit/Source/core/inspector/ConsoleMessage.h +++ b/third_party/WebKit/Source/core/inspector/ConsoleMessage.h
@@ -17,6 +17,7 @@ class DocumentLoader; class LocalFrame; class SourceLocation; +class WorkerThread; class CORE_EXPORT ConsoleMessage final : public GarbageCollectedFinalized<ConsoleMessage> { @@ -44,7 +45,7 @@ static ConsoleMessage* CreateFromWorker(MessageLevel, const String& message, std::unique_ptr<SourceLocation>, - const String& worker_id); + WorkerThread*); ~ConsoleMessage();
diff --git a/third_party/WebKit/Source/core/inspector/IdentifiersFactory.cpp b/third_party/WebKit/Source/core/inspector/IdentifiersFactory.cpp index 772448c..bbf7c3a2 100644 --- a/third_party/WebKit/Source/core/inspector/IdentifiersFactory.cpp +++ b/third_party/WebKit/Source/core/inspector/IdentifiersFactory.cpp
@@ -65,21 +65,17 @@ // static String IdentifiersFactory::FrameId(Frame* frame) { - if (!frame) - return g_empty_string; - const base::UnguessableToken& token = frame->GetDevToolsFrameToken(); - // token.ToString() is latin1. - return String(token.ToString().c_str()); + return frame ? IdFromToken(frame->GetDevToolsFrameToken()) : g_empty_string; } // static LocalFrame* IdentifiersFactory::FrameById(InspectedFrames* inspected_frames, const String& frame_id) { for (auto* frame : *inspected_frames) { - const base::UnguessableToken& token = frame->GetDevToolsFrameToken(); - // token.ToString() is latin1. - if (frame->Client() && frame_id == token.ToString().c_str()) + if (frame->Client() && + frame_id == IdFromToken(frame->GetDevToolsFrameToken())) { return frame; + } } return nullptr; } @@ -94,6 +90,14 @@ } // static +String IdentifiersFactory::IdFromToken(const base::UnguessableToken& token) { + if (token.is_empty()) + return g_empty_string; + // token.ToString() is latin1. + return String(token.ToString().c_str()); +} + +// static String IdentifiersFactory::AddProcessIdPrefixTo(int id) { static uint32_t process_id = Platform::Current()->GetUniqueIdForProcess();
diff --git a/third_party/WebKit/Source/core/inspector/IdentifiersFactory.h b/third_party/WebKit/Source/core/inspector/IdentifiersFactory.h index 3d79ce8..c542870 100644 --- a/third_party/WebKit/Source/core/inspector/IdentifiersFactory.h +++ b/third_party/WebKit/Source/core/inspector/IdentifiersFactory.h
@@ -26,6 +26,7 @@ #ifndef IdentifiersFactory_h #define IdentifiersFactory_h +#include "base/unguessable_token.h" #include "core/CoreExport.h" #include "platform/wtf/Allocator.h" #include "platform/wtf/text/WTFString.h" @@ -55,6 +56,8 @@ static String LoaderId(DocumentLoader*); + static String IdFromToken(const base::UnguessableToken&); + private: static String AddProcessIdPrefixTo(int id); static int RemoveProcessIdPrefixFrom(const String&, bool* ok);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp index dfa12dc..c996f5c 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -831,7 +831,7 @@ return response; DummyExceptionStateForTesting exception_state; - Element* new_elem = old_element->GetDocument().createElement( + Element* new_elem = old_element->GetDocument().CreateElementForBinding( AtomicString(tag_name), exception_state); if (exception_state.HadException()) return ToResponse(exception_state);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp index 8501021..a284cf8 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
@@ -84,6 +84,8 @@ namespace blink { +using GetRequestPostDataCallback = + protocol::Network::Backend::GetRequestPostDataCallback; using GetResponseBodyCallback = protocol::Network::Backend::GetResponseBodyCallback; using protocol::Response; @@ -153,13 +155,8 @@ public: InspectorFileReaderLoaderClient( scoped_refptr<BlobDataHandle> blob, - const String& mime_type, - const String& text_encoding_name, - std::unique_ptr<GetResponseBodyCallback> callback) - : blob_(std::move(blob)), - mime_type_(mime_type), - text_encoding_name_(text_encoding_name), - callback_(std::move(callback)) { + base::OnceCallback<void(scoped_refptr<SharedBuffer>)> callback) + : blob_(std::move(blob)), callback_(std::move(callback)) { loader_ = FileReaderLoader::Create(FileReaderLoader::kReadByClient, this); } @@ -179,38 +176,114 @@ raw_data_->Append(data, data_length); } - void DidFinishLoading() override { - String result; - bool base64_encoded; - if (InspectorPageAgent::SharedBufferContent(raw_data_, mime_type_, - text_encoding_name_, &result, - &base64_encoded)) - callback_->sendSuccess(result, base64_encoded); - else - callback_->sendFailure(Response::Error("Couldn't encode data")); - Dispose(); - } + void DidFinishLoading() override { Done(raw_data_); } - void DidFail(FileError::ErrorCode) override { - callback_->sendFailure(Response::Error("Couldn't read BLOB")); - Dispose(); - } + void DidFail(FileError::ErrorCode) override { Done(nullptr); } private: - void Dispose() { - raw_data_ = nullptr; + void Done(scoped_refptr<SharedBuffer> output) { + std::move(callback_).Run(output); delete this; } scoped_refptr<BlobDataHandle> blob_; String mime_type_; String text_encoding_name_; - std::unique_ptr<GetResponseBodyCallback> callback_; + base::OnceCallback<void(scoped_refptr<SharedBuffer>)> callback_; std::unique_ptr<FileReaderLoader> loader_; scoped_refptr<SharedBuffer> raw_data_; DISALLOW_COPY_AND_ASSIGN(InspectorFileReaderLoaderClient); }; +static void ResponseBodyFileReaderLoaderDone( + const String& mime_type, + const String& text_encoding_name, + std::unique_ptr<GetResponseBodyCallback> callback, + scoped_refptr<SharedBuffer> raw_data) { + if (!raw_data) { + callback->sendFailure(Response::Error("Couldn't read BLOB")); + return; + } + String result; + bool base64_encoded; + if (InspectorPageAgent::SharedBufferContent( + raw_data, mime_type, text_encoding_name, &result, &base64_encoded)) { + callback->sendSuccess(result, base64_encoded); + } else { + callback->sendFailure(Response::Error("Couldn't encode data")); + } +} + +class InspectorPostBodyParser + : public WTF::RefCounted<InspectorPostBodyParser> { + public: + explicit InspectorPostBodyParser( + std::unique_ptr<GetRequestPostDataCallback> callback) + : callback_(std::move(callback)), error_(false) {} + + void Parse(ExecutionContext* context, EncodedFormData* request_body) { + if (!request_body || request_body->IsEmpty()) + return; + + parts_.Grow(request_body->Elements().size()); + for (size_t i = 0; i < request_body->Elements().size(); i++) { + const FormDataElement& data = request_body->Elements()[i]; + switch (data.type_) { + case FormDataElement::kData: + parts_[i] = String::FromUTF8WithLatin1Fallback(data.data_.data(), + data.data_.size()); + break; + case FormDataElement::kEncodedBlob: + ReadDataBlob(context, data.optional_blob_data_handle_, &parts_[i]); + break; + case FormDataElement::kEncodedFile: + case FormDataElement::kDataPipe: + // Do nothing, not supported + break; + } + } + } + + private: + friend class WTF::RefCounted<InspectorPostBodyParser>; + + ~InspectorPostBodyParser() { + if (error_) + return; + String result; + for (const auto& part : parts_) + result.append(part); + callback_->sendSuccess(result); + } + + void BlobReadCallback(String* destination, + scoped_refptr<SharedBuffer> raw_data) { + if (raw_data) { + *destination = String::FromUTF8WithLatin1Fallback(raw_data->Data(), + raw_data->size()); + } else { + error_ = true; + } + } + + void ReadDataBlob(ExecutionContext* context, + scoped_refptr<blink::BlobDataHandle> blob_handle, + String* destination) { + if (!blob_handle) + return; + auto* reader = new InspectorFileReaderLoaderClient( + blob_handle, + WTF::Bind(&InspectorPostBodyParser::BlobReadCallback, + WTF::RetainedRef(this), WTF::Unretained(destination))); + reader->Start(context); + } + + std::unique_ptr<GetRequestPostDataCallback> callback_; + bool error_; + Vector<String> parts_; + DISALLOW_COPY_AND_ASSIGN(InspectorPostBodyParser); +}; + KURL UrlWithoutFragment(const KURL& url) { KURL result = url; result.RemoveFragmentIdentifier(); @@ -369,10 +442,16 @@ *content = ""; if (!body || body->IsEmpty()) return false; + if (max_body_size != 0 && body->SizeInBytes() > max_body_size) + return true; + + for (const auto& element : body->Elements()) { + if (element.type_ != FormDataElement::kData) + return true; + } Vector<char> bytes; body->Flatten(bytes); - if (max_body_size == 0 || body->SizeInBytes() <= max_body_size) - *content = String::FromUTF8WithLatin1Fallback(bytes.data(), bytes.size()); + *content = String::FromUTF8WithLatin1Fallback(bytes.data(), bytes.size()); return true; } @@ -659,8 +738,8 @@ else if (request.HttpBody()) post_data = request.HttpBody()->DeepCopy(); - resources_data_->ResourceCreated(request_id, loader_id, request.Url(), - post_data); + resources_data_->ResourceCreated(execution_context, request_id, loader_id, + request.Url(), post_data); if (initiator_info.name == FetchInitiatorTypeNames::xmlhttprequest) type = InspectorPageAgent::kXHRResource; @@ -1006,8 +1085,7 @@ pending_request_ = client; pending_request_type_ = InspectorPageAgent::kXHRResource; pending_xhr_replay_data_ = XHRReplayData::Create( - xhr->GetExecutionContext(), method, UrlWithoutFragment(url), async, - include_credentials); + method, UrlWithoutFragment(url), async, include_credentials); for (const auto& header : headers) pending_xhr_replay_data_->AddHeader(header.key, header.value); } @@ -1361,8 +1439,10 @@ resources_data_->Data(request_id); BlobDataHandle* blob = resource_data->DownloadedFileBlob(); InspectorFileReaderLoaderClient* client = new InspectorFileReaderLoaderClient( - blob, resource_data->MimeType(), resource_data->TextEncodingName(), - std::move(callback)); + blob, + WTF::Bind(ResponseBodyFileReaderLoaderDone, resource_data->MimeType(), + resource_data->TextEncodingName(), + WTF::Passed(std::move(callback)))); if (worker_global_scope_) { client->Start(worker_global_scope_); return; @@ -1405,10 +1485,11 @@ String actual_request_id = request_id; XHRReplayData* xhr_replay_data = resources_data_->XhrReplayData(request_id); - if (!xhr_replay_data) + auto data = resources_data_->Data(request_id); + if (!xhr_replay_data || !data) return Response::Error("Given id does not correspond to XHR"); - ExecutionContext* execution_context = xhr_replay_data->GetExecutionContext(); + ExecutionContext* execution_context = data->GetExecutionContext(); if (execution_context->IsContextDestroyed()) { resources_data_->SetXHRReplayData(request_id, nullptr); return Response::Error("Document is already detached"); @@ -1426,7 +1507,6 @@ xhr->setRequestHeader(header.key, header.value, IGNORE_EXCEPTION_FOR_TESTING); } - auto data = resources_data_->Data(request_id); xhr->SendForInspectorXHRReplay(data ? data->PostData() : nullptr, IGNORE_EXCEPTION_FOR_TESTING); @@ -1671,11 +1751,9 @@ max_post_data_size_(0) { DCHECK((IsMainThread() && !worker_global_scope_) || (!IsMainThread() && worker_global_scope_)); - const base::UnguessableToken& token = + conditions_token_ = IdentifiersFactory::IdFromToken( worker_global_scope_ ? worker_global_scope_->GetParentDevToolsToken() - : inspected_frames->Root()->GetDevToolsFrameToken(); - // token.ToString() is latin1. - conditions_token_ = String(token.ToString().c_str()); + : inspected_frames->Root()->GetDevToolsFrameToken()); } void InspectorNetworkAgent::ShouldForceCORSPreflight(bool* result) { @@ -1683,15 +1761,27 @@ *result = true; } -Response InspectorNetworkAgent::getRequestPostData(const String& request_id, - String* post_data) { +void InspectorNetworkAgent::getRequestPostData( + const String& request_id, + std::unique_ptr<GetRequestPostDataCallback> callback) { NetworkResourcesData::ResourceData const* resource_data = resources_data_->Data(request_id); - if (!resource_data) - return Response::Error("No resource with given id was found"); - if (FormDataToString(resource_data->PostData(), 0, post_data)) - return Response::OK(); - return Response::Error("No post data available for the request"); + if (!resource_data) { + callback->sendFailure( + Response::Error("No resource with given id was found")); + return; + } + scoped_refptr<EncodedFormData> post_data = resource_data->PostData(); + if (!post_data || post_data->IsEmpty()) { + callback->sendFailure( + Response::Error("No post data available for the request")); + return; + } + + scoped_refptr<InspectorPostBodyParser> parser = + base::MakeRefCounted<InspectorPostBodyParser>(std::move(callback)); + // TODO(crbug.com/810554): Extend protocol to fetch body parts separately + parser->Parse(resource_data->GetExecutionContext(), post_data.get()); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h index 1eb12de..8a2438a6 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h
@@ -236,8 +236,8 @@ const String& origin, std::unique_ptr<protocol::Array<String>>* certificate) override; - protocol::Response getRequestPostData(const String& request_id, - String* post_data) override; + void getRequestPostData(const String& request_id, + std::unique_ptr<GetRequestPostDataCallback>) override; // Called from other agents. protocol::Response GetResponseBody(const String& request_id,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp index d52d9a3..d0e1e1e 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -1245,11 +1245,11 @@ std::unique_ptr<TracedValue> InspectorTracingSessionIdForWorkerEvent::Data( const String& session_id, - const String& worker_id, WorkerThread* worker_thread) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("sessionId", session_id); - value->SetString("workerId", worker_id); + value->SetString("workerId", IdentifiersFactory::IdFromToken( + worker_thread->GetDevToolsWorkerToken())); value->SetDouble("workerThreadId", worker_thread->GetPlatformThreadId()); return value; }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h index 432c823e..1a8d5a3 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h +++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
@@ -450,7 +450,6 @@ namespace InspectorTracingSessionIdForWorkerEvent { std::unique_ptr<TracedValue> Data(const String& session_id, - const String& worker_id, WorkerThread*); }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp index 5b904c4..7f4e4598 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp
@@ -10,8 +10,8 @@ #include "core/inspector/IdentifiersFactory.h" #include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectorTraceEvents.h" -#include "core/inspector/InspectorWorkerAgent.h" #include "core/loader/FrameLoader.h" +#include "core/workers/WorkerInspectorProxy.h" #include "platform/instrumentation/tracing/TraceEvent.h" namespace blink { @@ -29,20 +29,20 @@ } InspectorTracingAgent::InspectorTracingAgent(Client* client, - InspectorWorkerAgent* worker_agent, InspectedFrames* inspected_frames) : layer_tree_id_(0), client_(client), - worker_agent_(worker_agent), inspected_frames_(inspected_frames) {} +InspectorTracingAgent::~InspectorTracingAgent() {} + void InspectorTracingAgent::Trace(blink::Visitor* visitor) { - visitor->Trace(worker_agent_); visitor->Trace(inspected_frames_); InspectorBaseAgent::Trace(visitor); } void InspectorTracingAgent::Restore() { + state_->getString(TracingAgentState::kSessionId, &session_id_); EmitMetadataEvents(); } @@ -58,6 +58,10 @@ client_->HideReloadingBlanket(); } +void InspectorTracingAgent::DidStartWorker(WorkerInspectorProxy* proxy, bool) { + WriteTimelineStartedEventForWorker(proxy->GetWorkerThread()); +} + void InspectorTracingAgent::start(Maybe<String> categories, Maybe<String> options, Maybe<double> buffer_usage_reporting_interval, @@ -73,8 +77,8 @@ } instrumenting_agents_->addInspectorTracingAgent(this); - state_->setString(TracingAgentState::kSessionId, - IdentifiersFactory::CreateIdentifier()); + session_id_ = IdentifiersFactory::CreateIdentifier(); + state_->setString(TracingAgentState::kSessionId, session_id_); // Tracing is already started by DevTools TracingHandler::Start for the // renderer target in the browser process. It will eventually start tracing @@ -94,24 +98,34 @@ } bool InspectorTracingAgent::IsStarted() const { - return !SessionId().IsEmpty(); -} - -String InspectorTracingAgent::SessionId() const { - String result; - if (state_) - state_->getString(TracingAgentState::kSessionId, &result); - return result; + return !session_id_.IsEmpty(); } void InspectorTracingAgent::EmitMetadataEvents() { TRACE_EVENT_INSTANT1(kDevtoolsMetadataEventCategory, "TracingStartedInPage", TRACE_EVENT_SCOPE_THREAD, "data", InspectorTracingStartedInFrame::Data( - SessionId(), inspected_frames_->Root())); + session_id_, inspected_frames_->Root())); if (layer_tree_id_) SetLayerTreeId(layer_tree_id_); - worker_agent_->SetTracingSessionId(SessionId()); + for (WorkerInspectorProxy* proxy : WorkerInspectorProxy::AllProxies()) { + // For now we assume this is document. TODO(kinuko): Fix this. + DCHECK(proxy->GetExecutionContext()->IsDocument()); + Document* document = ToDocument(proxy->GetExecutionContext()); + if (proxy->GetWorkerThread() && document->GetFrame() && + inspected_frames_->Contains(document->GetFrame())) { + WriteTimelineStartedEventForWorker(proxy->GetWorkerThread()); + } + } +} + +void InspectorTracingAgent::WriteTimelineStartedEventForWorker( + WorkerThread* worker_thread) { + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), + "TracingSessionIdForWorker", TRACE_EVENT_SCOPE_THREAD, + "data", + InspectorTracingSessionIdForWorkerEvent::Data( + session_id_, worker_thread)); } void InspectorTracingAgent::SetLayerTreeId(int layer_tree_id) { @@ -119,7 +133,7 @@ TRACE_EVENT_INSTANT1( kDevtoolsMetadataEventCategory, "SetLayerTreeId", TRACE_EVENT_SCOPE_THREAD, "data", - InspectorSetLayerTreeId::Data(SessionId(), layer_tree_id_)); + InspectorSetLayerTreeId::Data(session_id_, layer_tree_id_)); } void InspectorTracingAgent::RootLayerCleared() { @@ -136,7 +150,7 @@ client_->HideReloadingBlanket(); instrumenting_agents_->removeInspectorTracingAgent(this); state_->remove(TracingAgentState::kSessionId); - worker_agent_->SetTracingSessionId(String()); + session_id_ = String(); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h index e95a1bc..bcf51398 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h
@@ -17,7 +17,8 @@ namespace blink { class InspectedFrames; -class InspectorWorkerAgent; +class WorkerInspectorProxy; +class WorkerThread; class CORE_EXPORT InspectorTracingAgent final : public InspectorBaseAgent<protocol::Tracing::Metainfo> { @@ -30,11 +31,8 @@ virtual void HideReloadingBlanket() = 0; }; - static InspectorTracingAgent* Create(Client* client, - InspectorWorkerAgent* worker_agent, - InspectedFrames* inspected_frames) { - return new InspectorTracingAgent(client, worker_agent, inspected_frames); - } + InspectorTracingAgent(Client*, InspectedFrames*); + ~InspectorTracingAgent() override; void Trace(blink::Visitor*) override; @@ -45,6 +43,7 @@ // InspectorInstrumentation methods void FrameStartedLoading(LocalFrame*, FrameLoadType); void FrameStoppedLoading(LocalFrame*); + void DidStartWorker(WorkerInspectorProxy*, bool); // Protocol method implementations. void start(protocol::Maybe<String> categories, @@ -61,16 +60,14 @@ void RootLayerCleared(); private: - InspectorTracingAgent(Client*, InspectorWorkerAgent*, InspectedFrames*); - void EmitMetadataEvents(); void InnerDisable(); - String SessionId() const; bool IsStarted() const; + void WriteTimelineStartedEventForWorker(WorkerThread*); int layer_tree_id_; Client* client_; - Member<InspectorWorkerAgent> worker_agent_; + String session_id_; Member<InspectedFrames> inspected_frames_; DISALLOW_COPY_AND_ASSIGN(InspectorTracingAgent);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp index 21d9378..9d4e93f0 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp
@@ -127,15 +127,6 @@ return Response::Error("Session id must be specified"); } -void InspectorWorkerAgent::SetTracingSessionId( - const String& tracing_session_id) { - tracing_session_id_ = tracing_session_id; - if (tracing_session_id.IsEmpty()) - return; - for (auto& id_proxy : connected_proxies_) - id_proxy.value->WriteTimelineStartedEvent(tracing_session_id); -} - void InspectorWorkerAgent::ShouldWaitForDebuggerOnWorkerStart(bool* result) { if (AutoAttachEnabled() && state_->booleanProperty(WorkerAgentState::kWaitForDebuggerOnStart, false)) @@ -146,8 +137,6 @@ bool waiting_for_debugger) { DCHECK(GetFrontend() && AutoAttachEnabled()); ConnectToProxy(proxy, waiting_for_debugger); - if (!tracing_session_id_.IsEmpty()) - proxy->WriteTimelineStartedEvent(tracing_session_id_); } void InspectorWorkerAgent::WorkerTerminated(WorkerInspectorProxy* proxy) {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h index 70a70ceb..d499d54d 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h
@@ -68,8 +68,6 @@ protocol::Maybe<String> session_id, protocol::Maybe<String> target_id) override; - void SetTracingSessionId(const String&); - private: bool AutoAttachEnabled(); void ConnectToAllProxies(); @@ -86,7 +84,6 @@ HeapHashMap<int, Member<WorkerInspectorProxy>> connected_proxies_; HashMap<int, String> connection_to_session_id_; HashMap<String, int> session_id_to_connection_; - String tracing_session_id_; static int s_last_connection_; DISALLOW_COPY_AND_ASSIGN(InspectorWorkerAgent); };
diff --git a/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp b/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp index 597c0be..6e17d58 100644 --- a/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp +++ b/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp
@@ -40,13 +40,12 @@ return status_code >= 400; } -XHRReplayData* XHRReplayData::Create(ExecutionContext* execution_context, - const AtomicString& method, +// static +XHRReplayData* XHRReplayData::Create(const AtomicString& method, const KURL& url, bool async, bool include_credentials) { - return new XHRReplayData(execution_context, method, url, async, - include_credentials); + return new XHRReplayData(method, url, async, include_credentials); } void XHRReplayData::AddHeader(const AtomicString& key, @@ -54,24 +53,19 @@ headers_.Set(key, value); } -XHRReplayData::XHRReplayData(ExecutionContext* execution_context, - const AtomicString& method, +XHRReplayData::XHRReplayData(const AtomicString& method, const KURL& url, bool async, bool include_credentials) - : execution_context_(execution_context), - method_(method), + : method_(method), url_(url), async_(async), include_credentials_(include_credentials) {} -void XHRReplayData::Trace(blink::Visitor* visitor) { - visitor->Trace(execution_context_); -} - // ResourceData NetworkResourcesData::ResourceData::ResourceData( NetworkResourcesData* network_resources_data, + ExecutionContext* execution_context, const String& request_id, const String& loader_id, const KURL& requested_url) @@ -85,7 +79,8 @@ http_status_code_(0), raw_header_size_(0), pending_encoded_data_length_(0), - cached_resource_(nullptr) {} + cached_resource_(nullptr), + execution_context_(execution_context) {} void NetworkResourcesData::ResourceData::Trace(blink::Visitor* visitor) { visitor->Trace(network_resources_data_); @@ -93,6 +88,7 @@ visitor->template RegisterWeakMembers< NetworkResourcesData::ResourceData, &NetworkResourcesData::ResourceData::ClearWeakMembers>(this); + visitor->Trace(execution_context_); } void NetworkResourcesData::ResourceData::SetContent(const String& content, @@ -194,13 +190,14 @@ } void NetworkResourcesData::ResourceCreated( + ExecutionContext* context, const String& request_id, const String& loader_id, const KURL& requested_url, scoped_refptr<EncodedFormData> post_data) { EnsureNoDataForRequestId(request_id); ResourceData* data = - new ResourceData(this, request_id, loader_id, requested_url); + new ResourceData(this, context, request_id, loader_id, requested_url); request_id_to_resource_data_map_.Set(request_id, data); if (post_data && PrepareToAddResourceData(request_id, post_data->SizeInBytes())) {
diff --git a/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h b/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h index dca17e0..ad424fa 100644 --- a/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h +++ b/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h
@@ -51,8 +51,7 @@ class XHRReplayData final : public GarbageCollectedFinalized<XHRReplayData> { public: - static XHRReplayData* Create(ExecutionContext*, - const AtomicString& method, + static XHRReplayData* Create(const AtomicString& method, const KURL&, bool async, bool include_credentials); @@ -63,18 +62,15 @@ bool Async() const { return async_; } const HTTPHeaderMap& Headers() const { return headers_; } bool IncludeCredentials() const { return include_credentials_; } - ExecutionContext* GetExecutionContext() const { return execution_context_; } - virtual void Trace(blink::Visitor*); + virtual void Trace(blink::Visitor*) {} private: - XHRReplayData(ExecutionContext*, - const AtomicString& method, + XHRReplayData(const AtomicString& method, const KURL&, bool async, bool include_credentials); - Member<ExecutionContext> execution_context_; AtomicString method_; KURL url_; bool async_; @@ -90,6 +86,7 @@ public: ResourceData(NetworkResourcesData*, + ExecutionContext*, const String& request_id, const String& loader_id, const KURL&); @@ -166,7 +163,7 @@ post_data_ = post_data; } scoped_refptr<EncodedFormData> PostData() const { return post_data_; } - + ExecutionContext* GetExecutionContext() const { return execution_context_; } void Trace(blink::Visitor*); private: @@ -199,6 +196,7 @@ scoped_refptr<BlobDataHandle> downloaded_file_blob_; Vector<AtomicString> certificate_; scoped_refptr<EncodedFormData> post_data_; + Member<ExecutionContext> execution_context_; }; static NetworkResourcesData* Create(size_t total_buffer_size, @@ -207,7 +205,8 @@ } ~NetworkResourcesData(); - void ResourceCreated(const String& request_id, + void ResourceCreated(ExecutionContext*, + const String& request_id, const String& loader_id, const KURL&, scoped_refptr<EncodedFormData>);
diff --git a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json index 99b781d..a68b231 100644 --- a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json +++ b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
@@ -97,7 +97,7 @@ "domain": "Network", "exclude": ["clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookies", "setCookie", "setCookies", "canEmulateNetworkConditions", "setRequestInterception", "continueInterceptedRequest", "getResponseBodyForInterception"], - "async": ["getResponseBody"] + "async": ["getResponseBody", "getRequestPostData"] }, { "domain": "Target",
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp index 2a94467..1a8bed1 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -1228,6 +1228,7 @@ LayoutUnit max_ascent, bool is_wrap_reverse) { switch (position) { + case ItemPosition::kLegacy: case ItemPosition::kAuto: case ItemPosition::kNormal: NOTREACHED();
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp index 4d834a3..6211995 100644 --- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -1898,6 +1898,7 @@ case ItemPosition::kBaseline: case ItemPosition::kLastBaseline: return kGridAxisStart; + case ItemPosition::kLegacy: case ItemPosition::kAuto: case ItemPosition::kNormal: case ItemPosition::kLeft: @@ -1980,6 +1981,7 @@ case ItemPosition::kBaseline: case ItemPosition::kLastBaseline: return kGridAxisStart; + case ItemPosition::kLegacy: case ItemPosition::kAuto: case ItemPosition::kNormal: break;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSectionTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSectionTest.cpp index e131ba9..e61954ae 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableSectionTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableSectionTest.cpp
@@ -18,15 +18,15 @@ } LayoutTableSection* CreateSection(unsigned rows, unsigned columns) { - auto* table = GetDocument().createElement("table"); + auto* table = GetDocument().CreateRawElement(HTMLNames::tableTag); GetDocument().body()->appendChild(table); - auto* section = GetDocument().createElement("tbody"); + auto* section = GetDocument().CreateRawElement(HTMLNames::tbodyTag); table->appendChild(section); for (unsigned i = 0; i < rows; ++i) { - auto* row = GetDocument().createElement("tr"); + auto* row = GetDocument().CreateRawElement(HTMLNames::trTag); section->appendChild(row); for (unsigned i = 0; i < columns; ++i) - row->appendChild(GetDocument().createElement("td")); + row->appendChild(GetDocument().CreateRawElement(HTMLNames::tdTag)); } GetDocument().View()->UpdateAllLifecyclePhases(); return ToLayoutTableSection(section->GetLayoutObject());
diff --git a/third_party/WebKit/Source/core/layout/LayoutText.cpp b/third_party/WebKit/Source/core/layout/LayoutText.cpp index 99351060..34c90bed 100644 --- a/third_party/WebKit/Source/core/layout/LayoutText.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
@@ -1960,8 +1960,6 @@ const NGOffsetMapping* LayoutText::GetNGOffsetMapping() const { if (!RuntimeEnabledFeatures::LayoutNGEnabled()) return nullptr; - // LayoutNG alternatives rely on |TextLength()| property, which is correct - // only when fragment painting is enabled. return NGOffsetMapping::GetFor(this); }
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc index 12c96bb2..af8a0ea 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
@@ -420,7 +420,7 @@ unsigned item_count_before = Items().size(); Element* parent = ToElement(layout_block_flow_->GetNode()); - Element* span = GetDocument().createElement("span"); + Element* span = GetDocument().CreateRawElement(HTMLNames::spanTag); parent->appendChild(span); // NeedsCollectInlines() is marked during the layout. @@ -446,7 +446,7 @@ Element* parent = GetElementById("x"); ASSERT_TRUE(parent); - Element* span = GetDocument().createElement("span"); + Element* span = GetDocument().CreateRawElement(HTMLNames::spanTag); parent->appendChild(span); // NeedsCollectInlines() is marked during the layout. @@ -491,7 +491,7 @@ unsigned item_count_before = Items().size(); Element* parent = ToElement(layout_block_flow_->GetNode()); - Element* span = GetDocument().createElement("span"); + Element* span = GetDocument().CreateRawElement(HTMLNames::spanTag); parent->appendChild(span); // NeedsCollectInlines() is marked during the layout. @@ -556,7 +556,7 @@ unsigned item_count_before = Items().size(); Element* parent = ToElement(layout_block_flow_->GetNode()); - Element* span = GetDocument().createElement("span"); + Element* span = GetDocument().CreateRawElement(HTMLNames::spanTag); parent->appendChild(span); // NeedsCollectInlines() is marked during the layout.
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc index b842d9a..8d907d6 100644 --- a/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc +++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc
@@ -201,6 +201,7 @@ } return NGBlockFlowPainter(*this).NodeAtPoint(result, location_in_container, + accumulated_offset, accumulated_offset, action); }
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScrollerTest.cpp b/third_party/WebKit/Source/core/page/scrolling/RootScrollerTest.cpp index 848d5d3..c6aef8be 100644 --- a/third_party/WebKit/Source/core/page/scrolling/RootScrollerTest.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/RootScrollerTest.cpp
@@ -215,7 +215,7 @@ Initialize("root-scroller.html"); Document* document = MainFrame()->GetDocument(); - Element* iframe = document->createElement("iframe"); + Element* iframe = document->CreateRawElement(HTMLNames::iframeTag); EXPECT_EQ(MainFrame()->GetDocument(), EffectiveRootScroller(MainFrame()->GetDocument())); @@ -1144,11 +1144,11 @@ Document* document = MainFrame()->GetDocument(); - Element* br = document->createElement("br"); + Element* br = document->CreateRawElement(HTMLNames::brTag); document->ReplaceChild(br, document->documentElement()); MainFrameView()->UpdateAllLifecyclePhases(); - Element* html = document->createElement("html"); - Element* body = document->createElement("body"); + Element* html = document->CreateRawElement(HTMLNames::htmlTag); + Element* body = document->CreateRawElement(HTMLNames::bodyTag); html->AppendChild(body); body->AppendChild(br); document->AppendChild(html);
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp index eda8f25..1c5b638 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
@@ -790,7 +790,7 @@ container->FirstFragment().PaintProperties()->OverflowClip(); EXPECT_EQ(FloatSize(80, 80), overflow_clip->ClipRect().Rect().Size()); - auto* new_style = GetDocument().createElement("style"); + auto* new_style = GetDocument().CreateRawElement(HTMLNames::styleTag); new_style->setTextContent("::-webkit-scrollbar {width: 40px; height: 40px}"); GetDocument().body()->AppendChild(new_style);
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_block_flow_painter.cc b/third_party/WebKit/Source/core/paint/ng/ng_block_flow_painter.cc index 91866ae..c3f4965 100644 --- a/third_party/WebKit/Source/core/paint/ng/ng_block_flow_painter.cc +++ b/third_party/WebKit/Source/core/paint/ng/ng_block_flow_painter.cc
@@ -29,10 +29,12 @@ HitTestResult& result, const HitTestLocation& location_in_container, const LayoutPoint& accumulated_offset, + const LayoutPoint& accumulated_offset_for_legacy, HitTestAction action) { if (const NGPaintFragment* paint_fragment = block_.PaintFragment()) { return NGBoxFragmentPainter(*paint_fragment) - .NodeAtPoint(result, location_in_container, accumulated_offset, action); + .NodeAtPoint(result, location_in_container, accumulated_offset, + accumulated_offset_for_legacy, action); } return false; }
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_block_flow_painter.h b/third_party/WebKit/Source/core/paint/ng/ng_block_flow_painter.h index 3e2ccc7..f107918 100644 --- a/third_party/WebKit/Source/core/paint/ng/ng_block_flow_painter.h +++ b/third_party/WebKit/Source/core/paint/ng/ng_block_flow_painter.h
@@ -32,6 +32,7 @@ bool NodeAtPoint(HitTestResult&, const HitTestLocation& location_in_container, const LayoutPoint& accumulated_offset, + const LayoutPoint& accumulated_offset_for_legacy, HitTestAction); private:
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc b/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc index 1e04ea0f7..1ae210a 100644 --- a/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc
@@ -715,6 +715,7 @@ HitTestResult& result, const HitTestLocation& location_in_container, const LayoutPoint& accumulated_offset, + const LayoutPoint& accumulated_offset_for_legacy, HitTestAction action) { // TODO(eae): Switch to using NG geometry types. LayoutSize offset(box_fragment_.Offset().left, box_fragment_.Offset().top); @@ -747,9 +748,13 @@ } } + // TODO(layout-dev): Accumulate |accumulated_offset_for_legacy| properly. + LayoutPoint adjusted_location_for_legacy = + accumulated_offset_for_legacy + offset; if (!skip_children && HitTestChildren(result, box_fragment_.Children(), location_in_container, - adjusted_location, action)) { + adjusted_location, adjusted_location_for_legacy, + action)) { return true; } @@ -831,6 +836,7 @@ const Vector<std::unique_ptr<NGPaintFragment>>& children, const HitTestLocation& location_in_container, const LayoutPoint& accumulated_offset, + const LayoutPoint& accumulated_offset_for_legacy, HitTestAction action) { for (auto iter = children.rbegin(); iter != children.rend(); iter++) { const std::unique_ptr<NGPaintFragment>& child = *iter; @@ -841,16 +847,24 @@ if (fragment.Type() == NGPhysicalFragment::kFragmentBox) { if (FragmentRequiresLegacyFallback(fragment)) { stop_hit_testing = fragment.GetLayoutObject()->NodeAtPoint( - result, location_in_container, accumulated_offset, action); + result, location_in_container, accumulated_offset_for_legacy, + action); } else { + // TODO(layout-dev): Accumulate |accumulated_offset_for_legacy| + // properly. stop_hit_testing = NGBoxFragmentPainter(*child).NodeAtPoint( - result, location_in_container, accumulated_offset, action); + result, location_in_container, accumulated_offset, + accumulated_offset_for_legacy, action); } } else if (fragment.Type() == NGPhysicalFragment::kFragmentLineBox) { - stop_hit_testing = - HitTestChildren(result, child->Children(), location_in_container, - accumulated_offset, action); + const LayoutSize line_box_offset(fragment.Offset().left, + fragment.Offset().top); + const LayoutPoint adjusted_offset = accumulated_offset + line_box_offset; + // TODO(layout-dev): Accumulate |accumulated_offset_for_legacy| properly. + stop_hit_testing = HitTestChildren(result, child->Children(), + location_in_container, adjusted_offset, + accumulated_offset_for_legacy, action); } else if (fragment.Type() == NGPhysicalFragment::kFragmentText) { // TODO(eae): Should this hit test on the text itself or the containing
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.h b/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.h index e03175c..f0d864e 100644 --- a/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.h +++ b/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.h
@@ -40,6 +40,7 @@ bool NodeAtPoint(HitTestResult&, const HitTestLocation& location_in_container, const LayoutPoint& accumulated_offset, + const LayoutPoint& accumulated_offset_for_legacy, HitTestAction); protected: @@ -113,6 +114,7 @@ const Vector<std::unique_ptr<NGPaintFragment>>&, const HitTestLocation& location_in_container, const LayoutPoint& accumulated_offset, + const LayoutPoint& accumulated_offset_for_legacy, HitTestAction); bool HitTestTextFragment(HitTestResult&, const NGPhysicalFragment&,
diff --git a/third_party/WebKit/Source/core/probe/CoreProbes.json5 b/third_party/WebKit/Source/core/probe/CoreProbes.json5 index 3387a39..620068d 100644 --- a/third_party/WebKit/Source/core/probe/CoreProbes.json5 +++ b/third_party/WebKit/Source/core/probe/CoreProbes.json5
@@ -195,6 +195,7 @@ probes: [ "frameStartedLoading", "frameStoppedLoading", + "didStartWorker", ] }, Worker: {
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index ce353eea..ec683f3e 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -221,7 +221,8 @@ StyleSelfAlignmentData ResolvedSelfAlignment( const StyleSelfAlignmentData& value, ItemPosition normal_value_behavior) { - if (value.GetPosition() == ItemPosition::kNormal || + if (value.GetPosition() == ItemPosition::kLegacy || + value.GetPosition() == ItemPosition::kNormal || value.GetPosition() == ItemPosition::kAuto) return {normal_value_behavior, OverflowAlignment::kDefault}; return value;
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h index 55cd077..68fe6237 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h +++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -193,6 +193,7 @@ } enum class ItemPosition : unsigned { + kLegacy, kAuto, kNormal, kStretch,
diff --git a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp index 00ae0ef7..6577ede 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp +++ b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp
@@ -103,9 +103,8 @@ DCHECK(IsParentContextThread()); if (asked_to_terminate_) return; - if (worker_inspector_proxy_) - worker_inspector_proxy_->AddConsoleMessageFromWorker(level, message, - std::move(location)); + execution_context_->AddConsoleMessage(ConsoleMessage::CreateFromWorker( + level, message, std::move(location), worker_thread_.get())); } void ThreadedMessagingProxyBase::ParentObjectDestroyed() {
diff --git a/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.cpp b/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.cpp index 5c80b8e6..b05552a 100644 --- a/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.cpp
@@ -45,10 +45,8 @@ const String& WorkerInspectorProxy::InspectorId() { if (inspector_id_.IsEmpty() && worker_thread_) { - const base::UnguessableToken& token = - worker_thread_->GetDevToolsWorkerToken(); - // token.ToString() is latin1. - inspector_id_ = String(token.ToString().c_str()); + inspector_id_ = IdentifiersFactory::IdFromToken( + worker_thread_->GetDevToolsWorkerToken()); } return inspector_id_; } @@ -96,14 +94,6 @@ it->value->DispatchMessageFromWorker(this, session_id, message); } -void WorkerInspectorProxy::AddConsoleMessageFromWorker( - MessageLevel level, - const String& message, - std::unique_ptr<SourceLocation> location) { - execution_context_->AddConsoleMessage(ConsoleMessage::CreateFromWorker( - level, message, std::move(location), InspectorId())); -} - static void ConnectToWorkerGlobalScopeInspectorTask(WorkerThread* worker_thread, int session_id) { if (WorkerInspectorController* inspector = @@ -163,17 +153,6 @@ } } -void WorkerInspectorProxy::WriteTimelineStartedEvent( - const String& tracing_session_id) { - if (!worker_thread_) - return; - TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), - "TracingSessionIdForWorker", TRACE_EVENT_SCOPE_THREAD, - "data", - InspectorTracingSessionIdForWorkerEvent::Data( - tracing_session_id, InspectorId(), worker_thread_)); -} - void WorkerInspectorProxy::Trace(blink::Visitor* visitor) { visitor->Trace(execution_context_); }
diff --git a/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.h b/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.h index 004ed14..2be672de5 100644 --- a/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.h +++ b/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.h
@@ -46,19 +46,16 @@ void WorkerThreadCreated(ExecutionContext*, WorkerThread*, const KURL&); void WorkerThreadTerminated(); void DispatchMessageFromWorker(int session_id, const String&); - void AddConsoleMessageFromWorker(MessageLevel, - const String& message, - std::unique_ptr<SourceLocation>); void ConnectToInspector(int session_id, PageInspector*); void DisconnectFromInspector(int session_id, PageInspector*); void SendMessageToInspector(int session_id, const String& message); - void WriteTimelineStartedEvent(const String& tracing_session_id); const String& Url() { return url_; } ExecutionContext* GetExecutionContext() { return execution_context_; } const String& InspectorId(); + WorkerThread* GetWorkerThread() { return worker_thread_; } using WorkerInspectorProxySet = PersistentHeapHashSet<WeakMember<WorkerInspectorProxy>>;
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js index 3cbb1eec..8538a91c 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
@@ -1159,10 +1159,7 @@ } _promptTextChanged() { - // Scroll to the bottom, except when the prompt is the only visible item. - if (this.itemCount() !== 0 && this._viewport.firstVisibleIndex() !== this.itemCount()) - this._immediatelyScrollToBottom(); - + this._viewport.setStickToBottom(this._messagesElement.isScrolledToBottom()); this._promptTextChangedForTest(); }
diff --git a/third_party/WebKit/Source/modules/BUILD.gn b/third_party/WebKit/Source/modules/BUILD.gn index 32ae4d9..c5e2a70 100644 --- a/third_party/WebKit/Source/modules/BUILD.gn +++ b/third_party/WebKit/Source/modules/BUILD.gn
@@ -161,7 +161,6 @@ "//third_party/WebKit/Source/modules/webusb", "//third_party/WebKit/Source/modules/xr", "//third_party/icu", - "//third_party/sqlite", "//third_party/zlib", ]
diff --git a/third_party/WebKit/Source/modules/accessibility/AXTableCell.cpp b/third_party/WebKit/Source/modules/accessibility/AXTableCell.cpp index 4c025637..7dde513 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXTableCell.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXTableCell.cpp
@@ -158,6 +158,14 @@ if (IsColumnHeaderCell()) return kColumnHeaderRole; + // This occurs in an edge case that mixes non-table CSS into a + // table, and <th role="gridcell">, see bug 798410. + // The odd CSS causes the <th> to not be a LayoutTableCell, + // and the ARIA role causes it to fall through to here, because + // it is not an ARIA/HTML column/row header. + if (!layout_object_ || !layout_object_->IsTableCell()) + return kCellRole; // <th role="gridcell">. + // Check the previous cell and the next cell on the same row. LayoutTableCell* layout_cell = ToLayoutTableCell(layout_object_); AccessibilityRole header_role = kCellRole;
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp index 2f2cc0d1..e1e26c4 100644 --- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp +++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -519,11 +519,8 @@ } TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) { - NonThrowableExceptionState non_throwable_exception_state; - Element* canvas_element = - GetDocument().createElement("canvas", non_throwable_exception_state); - EXPECT_FALSE(non_throwable_exception_state.HadException()); - HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(canvas_element); + auto* canvas = + ToHTMLCanvasElement(GetDocument().CreateRawElement(HTMLNames::canvasTag)); canvas->SetSize(IntSize(40, 40)); ImageBitmap* image_bitmap_derived = nullptr; {
diff --git a/third_party/WebKit/Source/modules/locks/LockManager.cpp b/third_party/WebKit/Source/modules/locks/LockManager.cpp index 5beca4b9..2bfcb3c 100644 --- a/third_party/WebKit/Source/modules/locks/LockManager.cpp +++ b/third_party/WebKit/Source/modules/locks/LockManager.cpp
@@ -173,14 +173,14 @@ LockManager::LockManager(ExecutionContext* context) : ContextLifecycleObserver(context) {} -ScriptPromise LockManager::acquire(ScriptState* script_state, +ScriptPromise LockManager::request(ScriptState* script_state, const String& name, V8LockGrantedCallback* callback, ExceptionState& exception_state) { - return acquire(script_state, name, LockOptions(), callback, exception_state); + return request(script_state, name, LockOptions(), callback, exception_state); } -ScriptPromise LockManager::acquire(ScriptState* script_state, +ScriptPromise LockManager::request(ScriptState* script_state, const String& name, const LockOptions& options, V8LockGrantedCallback* callback,
diff --git a/third_party/WebKit/Source/modules/locks/LockManager.h b/third_party/WebKit/Source/modules/locks/LockManager.h index 1337c63..0c93ae8 100644 --- a/third_party/WebKit/Source/modules/locks/LockManager.h +++ b/third_party/WebKit/Source/modules/locks/LockManager.h
@@ -28,11 +28,11 @@ public: explicit LockManager(ExecutionContext*); - ScriptPromise acquire(ScriptState*, + ScriptPromise request(ScriptState*, const String& name, V8LockGrantedCallback*, ExceptionState&); - ScriptPromise acquire(ScriptState*, + ScriptPromise request(ScriptState*, const String& name, const LockOptions&, V8LockGrantedCallback*,
diff --git a/third_party/WebKit/Source/modules/locks/LockManager.idl b/third_party/WebKit/Source/modules/locks/LockManager.idl index 74a41e5..de16e2a 100644 --- a/third_party/WebKit/Source/modules/locks/LockManager.idl +++ b/third_party/WebKit/Source/modules/locks/LockManager.idl
@@ -10,10 +10,10 @@ Exposed=(Window,Worker), RuntimeEnabled=LocksAPI ] interface LockManager { - [CallWith=ScriptState, RaisesException] Promise<Lock> acquire( + [CallWith=ScriptState, RaisesException] Promise<Lock> request( DOMString name, LockGrantedCallback callback); - [CallWith=ScriptState, RaisesException] Promise<Lock> acquire( + [CallWith=ScriptState, RaisesException] Promise<Lock> request( DOMString name, LockOptions options, LockGrantedCallback callback);
diff --git a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp index c1f08ec9..7d459bc 100644 --- a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp +++ b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
@@ -88,7 +88,7 @@ image->PaintImageForCurrentFrame().GetSkImage()->makeNonTextureImage(); SkBitmap sk_bitmap; - if (!sk_image->asLegacyBitmap(&sk_bitmap, SkImage::kRO_LegacyBitmapMode)) { + if (!sk_image->asLegacyBitmap(&sk_bitmap)) { // TODO(mcasas): retrieve the pixels from elsewhere. NOTREACHED(); resolver->Reject(DOMException::Create( @@ -159,8 +159,7 @@ SkBitmap sk_bitmap; - if (!sk_image || - !sk_image->asLegacyBitmap(&sk_bitmap, SkImage::kRO_LegacyBitmapMode)) { + if (!sk_image || !sk_image->asLegacyBitmap(&sk_bitmap)) { resolver->Reject(DOMException::Create( kInvalidStateError, "Failed to get image from current frame.")); return promise;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp index 2a41ab4..bbc9969 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp
@@ -264,26 +264,4 @@ return FramesPerBuffer() / static_cast<double>(sampleRate()); } -// TODO(crbug.com/764396): Remove these when fixed. -void AudioContext::CountValueSetterConflict(bool does_conflict) { - ++count_value_setter_calls_; - if (does_conflict) { - ++count_value_setter_conflicts_; - } -} - -void AudioContext::RecordValueSetterStatistics() { - DEFINE_STATIC_LOCAL( - LinearHistogram, value_setter_conflict_percentage_histogram, - ("WebAudio.AudioParam.ValueSetterConflictPercentage", 1, 100, 101)); - - value_setter_conflict_percentage_histogram.Count(static_cast<int32_t>( - 0.5 + 100.0 * count_value_setter_conflicts_ / count_value_setter_calls_)); - - UMA_HISTOGRAM_COUNTS_10000("WebAudio.AudioParam.ValueSetterCount", - count_value_setter_calls_); - UMA_HISTOGRAM_COUNTS_10000("WebAudio.AudioParam.ValueSetterConflictCount", - count_value_setter_conflicts_); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContext.h b/third_party/WebKit/Source/modules/webaudio/AudioContext.h index e78eb55..fc2335ba 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioContext.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioContext.h
@@ -44,10 +44,6 @@ void getOutputTimestamp(ScriptState*, AudioTimestamp&); double baseLatency() const; - // TODO(crbug.com/764396): Remove these when fixed. - void CountValueSetterConflict(bool does_conflict) final; - void RecordValueSetterStatistics() final; - protected: AudioContext(Document&, const WebAudioLatencyHint&); @@ -59,9 +55,6 @@ unsigned context_id_; Member<ScriptPromiseResolver> close_resolver_; - // TODO(crbug.com/764396): Remove these when fixed. - unsigned count_value_setter_calls_; - unsigned count_value_setter_conflicts_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp b/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp index 4c1990f..4990079 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp
@@ -247,9 +247,6 @@ // ---------------------------------------------------------------- -// TODO(crbug.com/764396): Remove this when fixed. -bool AudioParam::s_value_setter_warning_done_ = false; - AudioParam::AudioParam(BaseAudioContext& context, AudioParamType param_type, String param_name, @@ -296,9 +293,6 @@ } void AudioParam::setValue(float value) { - // TODO(crbug.com/764396): Remove this when fixed. - WarnIfSetterOverlapsEvent(); - WarnIfOutsideRange("value", value); Handler().SetValue(value); } @@ -314,16 +308,6 @@ Handler().SetValue(value); } -// TODO(crbug.com/764396): Remove this when fixed. -void AudioParam::WarnIfSetterOverlapsEvent() { - DCHECK(IsMainThread()); - - // Check for overlap and print a warning only if we haven't already - // printed a warning. - Handler().Timeline().WarnIfSetterOverlapsEvent( - Context(), Handler().GetParamName(), !s_value_setter_warning_done_); -} - float AudioParam::defaultValue() const { return Handler().DefaultValue(); }
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.h b/third_party/WebKit/Source/modules/webaudio/AudioParam.h index 2dd311ff..a772ab9 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParam.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.h
@@ -165,9 +165,6 @@ float IntrinsicValue() const { return NoBarrierLoad(&intrinsic_value_); } - // TODO(crbug.com/764396): remove this when fixed. - void WarnSetterOverlapsEvent(int event_index, BaseAudioContext&) const; - private: AudioParamHandler(BaseAudioContext&, AudioParamType, @@ -272,9 +269,6 @@ scoped_refptr<AudioParamHandler> handler_; Member<BaseAudioContext> context_; - // TODO(crbug.com/764396): Remove this method and attribute when fixed. - void WarnIfSetterOverlapsEvent(); - static bool s_value_setter_warning_done_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp index 3ca609e4..f9a860d 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp
@@ -1823,37 +1823,6 @@ return index; } -// TODO(crbug.com/764396): Remove this when fixed. -bool AudioParamTimeline::WarnIfSetterOverlapsEvent(BaseAudioContext* context, - String param_name, - bool print_warning) { - DCHECK(IsMainThread()); - - // Don't let the audio thread mutate the event list while we're - // examining the event list. - MutexLocker locker(events_lock_); - - // Find if there's an event at the current time. - bool has_overlap; - size_t current_event_index; - - std::tie(has_overlap, current_event_index) = - EventAtFrame(context->CurrentSampleFrame(), context->sampleRate()); - - context->CountValueSetterConflict(has_overlap); - - // Print a depecation message once, and also a more detailed message - // about the conflict so the developer knows. - Deprecation::CountDeprecation(context->GetExecutionContext(), - WebFeature::kWebAudioValueSetterIsSetValue); - if (print_warning && has_overlap) { - WarnSetterOverlapsEvent(param_name, current_event_index, *context); - return true; - } - - return false; -} - std::tuple<bool, size_t> AudioParamTimeline::EventAtFrame( size_t current_frame, float sample_rate) const {
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.h b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.h index 0f9dff0..547d09c 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.h
@@ -101,14 +101,6 @@ float SmoothedValue() { return smoothed_value_; } void SetSmoothedValue(float v) { smoothed_value_ = v; } - // TODO(crbug.com/764396): Remove this when the bug is fixed. - - // Print a warning if the value setter overlaps an event. Returns - // true if a warning was printed. - bool WarnIfSetterOverlapsEvent(BaseAudioContext*, - String param_name, - bool print_warning); - private: class ParamEvent { public:
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp index 4dba427..c3530c7 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp
@@ -189,9 +189,6 @@ RecordAutoplayStatus(); - // TODO(crbug.com/764396): Remove this when fixed. - RecordValueSetterStatistics(); - Clear(); }
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h index 7939ad2..33702e0 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h
@@ -341,10 +341,6 @@ // the first script evaluation. void NotifyWorkletIsReady(); - // TODO(crbug.com/764396): Remove this when fixed. - virtual void CountValueSetterConflict(bool does_conflict){}; - virtual void RecordValueSetterStatistics(){}; - protected: enum ContextType { kRealtimeContext, kOfflineContext };
diff --git a/third_party/WebKit/Source/modules/webdatabase/BUILD.gn b/third_party/WebKit/Source/modules/webdatabase/BUILD.gn index e07e267b..1908deb8 100644 --- a/third_party/WebKit/Source/modules/webdatabase/BUILD.gn +++ b/third_party/WebKit/Source/modules/webdatabase/BUILD.gn
@@ -77,6 +77,11 @@ "sqlite/SQLiteTransaction.h", ] + deps = [ + "//sql", + "//third_party/sqlite", + ] + if (is_win) { sources += [ "sqlite/SQLiteFileSystemWin.cpp" ] } else if (is_posix) {
diff --git a/third_party/WebKit/Source/modules/webdatabase/sqlite/DEPS b/third_party/WebKit/Source/modules/webdatabase/sqlite/DEPS index 581d3ec..1a2948b 100644 --- a/third_party/WebKit/Source/modules/webdatabase/sqlite/DEPS +++ b/third_party/WebKit/Source/modules/webdatabase/sqlite/DEPS
@@ -1,3 +1,4 @@ include_rules = [ + "+sql/initialization.h", "+third_party/sqlite/sqlite3.h", ]
diff --git a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteFileSystem.cpp b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteFileSystem.cpp index c88e015..bd38f0a 100644 --- a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteFileSystem.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteFileSystem.cpp
@@ -33,6 +33,7 @@ #include "platform/heap/Handle.h" #include "platform/heap/SafePoint.h" #include "platform/wtf/text/CString.h" +#include "sql/initialization.h" #include "third_party/sqlite/sqlite3.h" // SQLiteFileSystem::registerSQLiteVFS() is implemented in the @@ -51,7 +52,7 @@ initialize_sqlite_called_ = true; #endif // DCHECK_IS_ON() - sqlite3_initialize(); + sql::EnsureSqliteInitialized(); RegisterSQLiteVFS(); }
diff --git a/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp b/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp index 6f8e36d..bf806e3 100644 --- a/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp +++ b/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp
@@ -316,7 +316,9 @@ frame_transport_->FramePreImage(webgl_context->ContextGL()); - scoped_refptr<Image> image_ref = layer->TransferToStaticBitmapImage(); + std::unique_ptr<viz::SingleReleaseCallback> image_release_callback; + scoped_refptr<Image> image_ref = + layer->TransferToStaticBitmapImage(&image_release_callback); if (!image_ref) return; @@ -331,11 +333,10 @@ // longer require a texture copy. bool needs_copy = device_->external(); - // TODO(bajones): Pass through a callback to indicate that the image can be - // recycled. frame_transport_->FrameSubmit( presentation_provider_.get(), webgl_context->ContextGL(), webgl_context, - std::move(image_ref), nullptr, frame_id_, needs_copy); + std::move(image_ref), std::move(image_release_callback), frame_id_, + needs_copy); // Reset our frame id, since anything we'd want to do (resizing/etc) can // no-longer happen to this frame.
diff --git a/third_party/WebKit/Source/modules/xr/XRWebGLLayer.cpp b/third_party/WebKit/Source/modules/xr/XRWebGLLayer.cpp index 9b18485e..7961fff 100644 --- a/third_party/WebKit/Source/modules/xr/XRWebGLLayer.cpp +++ b/third_party/WebKit/Source/modules/xr/XRWebGLLayer.cpp
@@ -87,10 +87,11 @@ // Create an opaque WebGL Framebuffer WebGLFramebuffer* framebuffer = WebGLFramebuffer::CreateOpaque(webgl_context); - XRWebGLDrawingBuffer* drawing_buffer = XRWebGLDrawingBuffer::Create( - webgl_context->GetDrawingBuffer(), framebuffer->Object(), desired_size, - want_alpha_channel, want_depth_buffer, want_stencil_buffer, - want_antialiasing, want_multiview); + scoped_refptr<XRWebGLDrawingBuffer> drawing_buffer = + XRWebGLDrawingBuffer::Create( + webgl_context->GetDrawingBuffer(), framebuffer->Object(), + desired_size, want_alpha_channel, want_depth_buffer, + want_stencil_buffer, want_antialiasing, want_multiview); if (!drawing_buffer) { exception_state.ThrowDOMException(kOperationError, @@ -98,13 +99,13 @@ return nullptr; } - return new XRWebGLLayer(session, webgl_context, drawing_buffer, framebuffer, - framebuffer_scale); + return new XRWebGLLayer(session, webgl_context, std::move(drawing_buffer), + framebuffer, framebuffer_scale); } XRWebGLLayer::XRWebGLLayer(XRSession* session, WebGLRenderingContextBase* webgl_context, - XRWebGLDrawingBuffer* drawing_buffer, + scoped_refptr<XRWebGLDrawingBuffer> drawing_buffer, WebGLFramebuffer* framebuffer, double framebuffer_scale) : XRLayer(session, kXRWebGLLayerType), @@ -196,7 +197,7 @@ session()->device()->frameProvider()->SubmitWebGLLayer(this); } else if (session()->outputContext()) { ImageBitmap* image_bitmap = - ImageBitmap::Create(TransferToStaticBitmapImage()); + ImageBitmap::Create(TransferToStaticBitmapImage(nullptr)); session()->outputContext()->SetImage(image_bitmap); } } @@ -210,8 +211,9 @@ viewports_dirty_ = true; } -scoped_refptr<StaticBitmapImage> XRWebGLLayer::TransferToStaticBitmapImage() { - return drawing_buffer_->TransferToStaticBitmapImage(); +scoped_refptr<StaticBitmapImage> XRWebGLLayer::TransferToStaticBitmapImage( + std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) { + return drawing_buffer_->TransferToStaticBitmapImage(out_release_callback); } void XRWebGLLayer::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/modules/xr/XRWebGLLayer.h b/third_party/WebKit/Source/modules/xr/XRWebGLLayer.h index 3f10d63..e24d903 100644 --- a/third_party/WebKit/Source/modules/xr/XRWebGLLayer.h +++ b/third_party/WebKit/Source/modules/xr/XRWebGLLayer.h
@@ -11,6 +11,11 @@ #include "modules/xr/XRLayer.h" #include "modules/xr/XRWebGLLayerInit.h" #include "platform/graphics/gpu/XRWebGLDrawingBuffer.h" +#include "platform/wtf/RefCounted.h" + +namespace viz { +class SingleReleaseCallback; +} namespace blink { @@ -59,7 +64,8 @@ void OnFrameEnd() override; void OnResize() override; - scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage(); + scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage( + std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback); virtual void Trace(blink::Visitor*); virtual void TraceWrappers(const ScriptWrappableVisitor*) const; @@ -67,7 +73,7 @@ private: XRWebGLLayer(XRSession*, WebGLRenderingContextBase*, - XRWebGLDrawingBuffer*, + scoped_refptr<XRWebGLDrawingBuffer>, WebGLFramebuffer*, double framebuffer_scale); @@ -75,7 +81,7 @@ Member<XRViewport> right_viewport_; TraceWrapperMember<WebGLRenderingContextBase> webgl_context_; - std::unique_ptr<XRWebGLDrawingBuffer> drawing_buffer_; + scoped_refptr<XRWebGLDrawingBuffer> drawing_buffer_; Member<WebGLFramebuffer> framebuffer_; double framebuffer_scale_ = 1.0;
diff --git a/third_party/WebKit/Source/platform/DragImage.cpp b/third_party/WebKit/Source/platform/DragImage.cpp index 6d0001d..53976d99 100644 --- a/third_party/WebKit/Source/platform/DragImage.cpp +++ b/third_party/WebKit/Source/platform/DragImage.cpp
@@ -170,10 +170,8 @@ SkBitmap bm; paint_image = ResizeAndOrientImage(paint_image, orientation, image_scale, opacity, interpolation_quality); - if (!paint_image || !paint_image.GetSkImage()->asLegacyBitmap( - &bm, SkImage::kRO_LegacyBitmapMode)) { + if (!paint_image || !paint_image.GetSkImage()->asLegacyBitmap(&bm)) return nullptr; - } return WTF::WrapUnique( new DragImage(bm, device_scale_factor, interpolation_quality));
diff --git a/third_party/WebKit/Source/platform/exported/WebImage.cpp b/third_party/WebKit/Source/platform/exported/WebImage.cpp index 1af970a..753e4b3 100644 --- a/third_party/WebKit/Source/platform/exported/WebImage.cpp +++ b/third_party/WebKit/Source/platform/exported/WebImage.cpp
@@ -189,7 +189,7 @@ } if (sk_sp<SkImage> sk_image = paint_image.GetSkImage()) - sk_image->asLegacyBitmap(&bitmap_, SkImage::kRO_LegacyBitmapMode); + sk_image->asLegacyBitmap(&bitmap_); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/XRWebGLDrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/XRWebGLDrawingBuffer.cpp index 13526cfd60..1380980 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/XRWebGLDrawingBuffer.cpp +++ b/third_party/WebKit/Source/platform/graphics/gpu/XRWebGLDrawingBuffer.cpp
@@ -16,7 +16,22 @@ // to the more narrow use case. It may make sense in the future to abstract out // some of the common bits into a base class? -XRWebGLDrawingBuffer* XRWebGLDrawingBuffer::Create( +XRWebGLDrawingBuffer::ColorBuffer::ColorBuffer( + XRWebGLDrawingBuffer* drawing_buffer, + const IntSize& size, + GLuint texture_id) + : drawing_buffer(drawing_buffer), size(size), texture_id(texture_id) { + drawing_buffer->ContextGL()->GenMailboxCHROMIUM(mailbox.name); +} + +XRWebGLDrawingBuffer::ColorBuffer::~ColorBuffer() { + gpu::gles2::GLES2Interface* gl = drawing_buffer->ContextGL(); + if (receive_sync_token.HasData()) + gl->WaitSyncTokenCHROMIUM(receive_sync_token.GetConstData()); + gl->DeleteTextures(1, &texture_id); +} + +scoped_refptr<XRWebGLDrawingBuffer> XRWebGLDrawingBuffer::Create( DrawingBuffer* drawing_buffer, GLuint framebuffer, const IntSize& size, @@ -67,10 +82,11 @@ // TODO(bajones): Support multiview. bool multiview_supported = false; - XRWebGLDrawingBuffer* xr_drawing_buffer = new XRWebGLDrawingBuffer( - drawing_buffer, framebuffer, discard_framebuffer_supported, - want_alpha_channel, want_depth_buffer, want_stencil_buffer, - multiview_supported); + scoped_refptr<XRWebGLDrawingBuffer> xr_drawing_buffer = + base::AdoptRef(new XRWebGLDrawingBuffer( + drawing_buffer, framebuffer, discard_framebuffer_supported, + want_alpha_channel, want_depth_buffer, want_stencil_buffer, + multiview_supported)); if (!xr_drawing_buffer->Initialize(size, multisample_supported, multiview_supported)) { DLOG(ERROR) << "XRWebGLDrawingBuffer Initialization Failed"; @@ -137,6 +153,10 @@ return true; } +gpu::gles2::GLES2Interface* XRWebGLDrawingBuffer::ContextGL() { + return drawing_buffer_->ContextGL(); +} + bool XRWebGLDrawingBuffer::ContextLost() { return drawing_buffer_->destroyed(); } @@ -211,25 +231,16 @@ gl->BindFramebuffer(GL_FRAMEBUFFER, resolved_framebuffer_); } - if (back_color_buffer_) { - gl->DeleteTextures(1, &back_color_buffer_); - back_color_buffer_ = 0; - } - if (front_color_buffer_) { - gl->DeleteTextures(1, &front_color_buffer_); - front_color_buffer_ = 0; - } - back_color_buffer_ = CreateColorBuffer(); - front_color_buffer_ = CreateColorBuffer(); + front_color_buffer_ = nullptr; if (anti_aliasing_mode_ == kMSAAImplicitResolve) { - gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, back_color_buffer_, 0, - sample_count_); + gl->FramebufferTexture2DMultisampleEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + back_color_buffer_->texture_id, 0, sample_count_); } else { gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, back_color_buffer_, 0); + GL_TEXTURE_2D, back_color_buffer_->texture_id, 0); } if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { @@ -241,7 +252,8 @@ client->DrawingBufferClientRestoreFramebufferBinding(); } -GLuint XRWebGLDrawingBuffer::CreateColorBuffer() { +scoped_refptr<XRWebGLDrawingBuffer::ColorBuffer> +XRWebGLDrawingBuffer::CreateColorBuffer() { gpu::gles2::GLES2Interface* gl = drawing_buffer_->ContextGL(); GLuint texture_id = 0; @@ -265,7 +277,22 @@ DrawingBuffer::Client* client = drawing_buffer_->client(); client->DrawingBufferClientRestoreTexture2DBinding(); - return texture_id; + return base::AdoptRef(new ColorBuffer(this, size_, texture_id)); +} + +scoped_refptr<XRWebGLDrawingBuffer::ColorBuffer> +XRWebGLDrawingBuffer::CreateOrRecycleColorBuffer() { + if (!recycled_color_buffer_queue_.IsEmpty()) { + scoped_refptr<ColorBuffer> recycled = + recycled_color_buffer_queue_.TakeLast(); + if (recycled->receive_sync_token.HasData()) { + gpu::gles2::GLES2Interface* gl = drawing_buffer_->ContextGL(); + gl->WaitSyncTokenCHROMIUM(recycled->receive_sync_token.GetData()); + } + DCHECK(recycled->size == size_); + return recycled; + } + return CreateColorBuffer(); } bool XRWebGLDrawingBuffer::WantExplicitResolve() const { @@ -302,23 +329,16 @@ } // Swap buffers - GLuint tmp = back_color_buffer_; - - if (front_color_buffer_) { - back_color_buffer_ = front_color_buffer_; - } else { - back_color_buffer_ = CreateColorBuffer(); - } - - front_color_buffer_ = tmp; + front_color_buffer_ = back_color_buffer_; + back_color_buffer_ = CreateOrRecycleColorBuffer(); if (anti_aliasing_mode_ == kMSAAImplicitResolve) { - gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, back_color_buffer_, 0, - sample_count_); + gl->FramebufferTexture2DMultisampleEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + back_color_buffer_->texture_id, 0, sample_count_); } else { gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, back_color_buffer_, 0); + GL_TEXTURE_2D, back_color_buffer_->texture_id, 0); } if (discard_framebuffer_supported_) { @@ -331,29 +351,23 @@ } scoped_refptr<StaticBitmapImage> -XRWebGLDrawingBuffer::TransferToStaticBitmapImage() { - gpu::Mailbox mailbox; - gpu::SyncToken sync_token; +XRWebGLDrawingBuffer::TransferToStaticBitmapImage( + std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) { + gpu::gles2::GLES2Interface* gl = drawing_buffer_->ContextGL(); + scoped_refptr<ColorBuffer> buffer; bool success = false; - GLuint texture_id = 0; // Ensure the context isn't lost before continuing. if (!ContextLost()) { - gpu::gles2::GLES2Interface* gl = drawing_buffer_->ContextGL(); - SwapColorBuffers(); - gl->GenMailboxCHROMIUM(mailbox.name); - gl->ProduceTextureDirectCHROMIUM(front_color_buffer_, mailbox.name); - gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); + buffer = front_color_buffer_; + + gl->ProduceTextureDirectCHROMIUM(buffer->texture_id, buffer->mailbox.name); + gl->GenUnverifiedSyncTokenCHROMIUM(buffer->produce_sync_token.GetData()); // This should only fail if the context is lost during the buffer swap. - if (sync_token.HasData()) { - // Once we place the texture in the StaticBitmapImage it's effectively - // gone for good. So we'll null out the front_color_buffer_ here to ensure - // that a new one is created on the next swap. - texture_id = front_color_buffer_; - front_color_buffer_ = 0; + if (buffer->produce_sync_token.HasData()) { success = true; } } @@ -368,9 +382,55 @@ return StaticBitmapImage::Create(surface->makeImageSnapshot()); } + // This holds a ref on the XRWebGLDrawingBuffer that will keep it alive + // until the mailbox is released (and while the callback is running). + auto func = WTF::Bind(&XRWebGLDrawingBuffer::MailboxReleased, + scoped_refptr<XRWebGLDrawingBuffer>(this), buffer); + + std::unique_ptr<viz::SingleReleaseCallback> release_callback = + viz::SingleReleaseCallback::Create(std::move(func)); + + // Make our own textureId that is a reference on the same texture backing + // being used as the front buffer. We do not need to wait on the sync + // token since the mailbox was produced on the same GL context that we are + // using here. Similarly, the release callback will run on the same context so + // we don't need to send a sync token for this consume action back to it. + GLuint texture_id = gl->CreateAndConsumeTextureCHROMIUM(buffer->mailbox.name); + + if (out_release_callback) { + *out_release_callback = std::move(release_callback); + } else { + release_callback->Run(gpu::SyncToken(), true /* lost_resource */); + } + return AcceleratedStaticBitmapImage::CreateFromWebGLContextImage( - mailbox, sync_token, texture_id, + buffer->mailbox, buffer->produce_sync_token, texture_id, drawing_buffer_->ContextProviderWeakPtr(), size_); } +void XRWebGLDrawingBuffer::MailboxReleased( + scoped_refptr<ColorBuffer> color_buffer, + const gpu::SyncToken& sync_token, + bool lost_resource) { + // If the mailbox has been returned by the compositor then it is no + // longer being presented, and so is no longer the front buffer. + if (color_buffer == front_color_buffer_) + front_color_buffer_ = nullptr; + + // Update the SyncToken to ensure that we will wait for it even if we + // immediately destroy this buffer. + color_buffer->receive_sync_token = sync_token; + + if (drawing_buffer_->destroyed() || color_buffer->size != size_ || + lost_resource) { + return; + } + + const size_t cache_limit = 2; + while (recycled_color_buffer_queue_.size() >= cache_limit) + recycled_color_buffer_queue_.TakeLast(); + + recycled_color_buffer_queue_.push_front(color_buffer); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/XRWebGLDrawingBuffer.h b/third_party/WebKit/Source/platform/graphics/gpu/XRWebGLDrawingBuffer.h index 9fedc84..3535c6b 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/XRWebGLDrawingBuffer.h +++ b/third_party/WebKit/Source/platform/graphics/gpu/XRWebGLDrawingBuffer.h
@@ -5,28 +5,34 @@ #ifndef XRWebGLDrawingBuffer_h #define XRWebGLDrawingBuffer_h +#include "cc/layers/texture_layer_client.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "platform/PlatformExport.h" #include "platform/geometry/IntSize.h" #include "platform/heap/Handle.h" +#include "platform/wtf/Deque.h" +#include "platform/wtf/Noncopyable.h" +#include "platform/wtf/RefCounted.h" namespace blink { class DrawingBuffer; class StaticBitmapImage; -class PLATFORM_EXPORT XRWebGLDrawingBuffer { +class PLATFORM_EXPORT XRWebGLDrawingBuffer + : public RefCounted<XRWebGLDrawingBuffer> { public: - static XRWebGLDrawingBuffer* Create(DrawingBuffer*, - GLuint framebuffer, - const IntSize&, - bool want_alpha_channel, - bool want_depth_buffer, - bool want_stencil_buffer, - bool want_antialiasing, - bool want_multiview); + static scoped_refptr<XRWebGLDrawingBuffer> Create(DrawingBuffer*, + GLuint framebuffer, + const IntSize&, + bool want_alpha_channel, + bool want_depth_buffer, + bool want_stencil_buffer, + bool want_antialiasing, + bool want_multiview); + gpu::gles2::GLES2Interface* ContextGL(); bool ContextLost(); const IntSize& size() const { return size_; } @@ -39,9 +45,35 @@ void Resize(const IntSize&); - scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage(); + scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage( + std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback); private: + struct ColorBuffer : public RefCounted<ColorBuffer> { + ColorBuffer(XRWebGLDrawingBuffer*, const IntSize&, GLuint texture_id); + ~ColorBuffer(); + + // The owning XRWebGLDrawingBuffer. Note that DrawingBuffer is explicitly + // destroyed by the beginDestruction method, which will eventually drain all + // of its ColorBuffers. + scoped_refptr<XRWebGLDrawingBuffer> drawing_buffer; + const IntSize size; + const GLuint texture_id = 0; + + // The mailbox used to send this buffer to the compositor. + gpu::Mailbox mailbox; + + // The sync token for when this buffer was sent to the compositor. + gpu::SyncToken produce_sync_token; + + // The sync token for when this buffer was received back from the + // compositor. + gpu::SyncToken receive_sync_token; + + private: + WTF_MAKE_NONCOPYABLE(ColorBuffer); + }; + XRWebGLDrawingBuffer(DrawingBuffer*, GLuint framebuffer, bool discard_framebuffer_supported, @@ -52,22 +84,30 @@ bool Initialize(const IntSize&, bool use_multisampling, bool use_multiview); - GLuint CreateColorBuffer(); + scoped_refptr<ColorBuffer> CreateColorBuffer(); + scoped_refptr<ColorBuffer> CreateOrRecycleColorBuffer(); bool WantExplicitResolve() const; void SwapColorBuffers(); + void MailboxReleased(scoped_refptr<ColorBuffer>, + const gpu::SyncToken&, + bool lost_resource); + // Reference to the DrawingBuffer that owns the GL context for this object. scoped_refptr<DrawingBuffer> drawing_buffer_; const GLuint framebuffer_ = 0; GLuint resolved_framebuffer_ = 0; GLuint multisample_renderbuffer_ = 0; - GLuint back_color_buffer_ = 0; - GLuint front_color_buffer_ = 0; + scoped_refptr<ColorBuffer> back_color_buffer_ = 0; + scoped_refptr<ColorBuffer> front_color_buffer_ = 0; GLuint depth_stencil_buffer_ = 0; IntSize size_; + // Color buffers that were released by the XR compositor can be used again. + Deque<scoped_refptr<ColorBuffer>> recycled_color_buffer_queue_; + bool discard_framebuffer_supported_; bool depth_; bool stencil_;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp index b31d3eed..82b4f80 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
@@ -245,18 +245,10 @@ if (local_state.Clip() == ancestor_state.Clip()) return FloatClipRect(); - FloatClipRect result; bool success = false; - - if (local_state.Effect() != ancestor_state.Effect()) { - SlowLocalToAncestorVisualRectWithEffects(local_state, ancestor_state, - result, clip_behavior, success); - } else { - result = LocalToAncestorClipRectInternal( - local_state.Clip(), ancestor_state.Clip(), ancestor_state.Transform(), - clip_behavior, success); - } - + auto result = LocalToAncestorClipRectInternal( + local_state.Clip(), ancestor_state.Clip(), ancestor_state.Transform(), + clip_behavior, success); DCHECK(success); return result; }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h index be6ceb4..dc74b84e 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h
@@ -57,8 +57,13 @@ const TransformPaintPropertyNode* destination_transform_node, FloatRect& mapping_rect); - // Returns the "clip visual rect" between |local_state| and |ancestor_state|. - // See above for the definition of "clip visual rect". + // Returns the clip rect between |local_state| and |ancestor_state|. The clip + // rect is the total clip rect that should be applied when painting contents + // of |local_state| in |ancestor_state| space. Because this clip rect applies + // on contents of |local_state|, it's not affected by any effect nodes between + // |local_state| and |ancestor_state|. + // + // Note that the clip of |ancestor_state| is *not* applied. // // The output FloatClipRect may contain false positives for rounded-ness // if a rounded clip is clipped out, and overly conservative results @@ -69,10 +74,14 @@ OverlayScrollbarClipBehavior = kIgnorePlatformOverlayScrollbarSize); // Maps from a rect in |local_state| to its visual rect in |ancestor_state|. - // This is computed by multiplying the rect by its combined transform between - // |local_state| and |ancestor_space|, then flattening into 2D space, then - // intersecting by the "clip visual rect" for |local_state|'s clips. See above - // for the definition of "clip visual rect". + // If there is no effect node between |local_state| (included) and + // |ancestor_state| (not included), the result is computed by multiplying the + // rect by its combined transform between |local_state| and |ancestor_space|, + // then flattening into 2D space, then intersecting by the clip for + // |local_state|'s clips. If there are any pixel-moving effect nodes between + // |local_state| and |ancestor_state|, for each segment of states separated + // by the effect nodes, we'll execute the above process and map the result + // rect with the effect. // // Note that the clip of |ancestor_state| is *not* applied. //
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp index d9c39ba..a7c4195 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
@@ -133,7 +133,6 @@ // this macro. #define CHECK_MAPPINGS() \ do { \ - EXPECT_TRUE(expected_clip.Rect().Contains(expected_visual_rect.Rect())); \ CHECK_LOCAL_TO_ANCESTOR_VISUAL_RECT(); \ CHECK_LOCAL_TO_ANCESTOR_CLIP_RECT(); \ CHECK_SOURCE_TO_DESTINATION_RECT(); \ @@ -649,8 +648,7 @@ expected_transformed_rect = expected_transform.MapRect(input_rect); expected_visual_rect = FloatClipRect(output); expected_visual_rect.ClearIsTight(); - expected_clip = FloatClipRect(FloatRect(-10, 0, 150, 150)); - expected_clip.ClearIsTight(); + expected_clip = FloatClipRect(FloatRect(50, 60, 90, 90)); CHECK_MAPPINGS(); }
diff --git a/third_party/WebKit/Tools/Scripts/audit-non-blink-usage.py b/third_party/WebKit/Tools/Scripts/audit-non-blink-usage.py index 2a1253a..1e3c2ac6 100755 --- a/third_party/WebKit/Tools/Scripts/audit-non-blink-usage.py +++ b/third_party/WebKit/Tools/Scripts/audit-non-blink-usage.py
@@ -164,6 +164,12 @@ 'base::TimeDelta', ], }, + { + 'paths': [ + 'third_party/WebKit/Source/modules/webdatabase/', + ], + 'allowed': ['sql::.+'], + }, ]
diff --git a/third_party/WebKit/public/platform/web_feature.mojom b/third_party/WebKit/public/platform/web_feature.mojom index fe4aee07..e497921 100644 --- a/third_party/WebKit/public/platform/web_feature.mojom +++ b/third_party/WebKit/public/platform/web_feature.mojom
@@ -1699,7 +1699,6 @@ kBatteryStatusInsecureOrigin = 2199, kBatteryStatusCrossOrigin = 2200, kBatteryStatusSameOriginABA = 2201, - kWebAudioValueSetterIsSetValue = 2202, kHasIDClassTagAttribute = 2203, kHasBeforeOrAfterPseudoElement = 2204, kShapeOutsideMaybeAffectedInlineSize = 2205, @@ -1864,6 +1863,7 @@ kCertificateTransparencyNonCompliantResourceInSubframe = 2360, kV8AbortController_Constructor = 2361, kReplaceCharsetInXHRIgnoringCase = 2362, + kHTMLIFrameElementGestureMedia = 2363, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/boringssl/BUILD.generated.gni b/third_party/boringssl/BUILD.generated.gni index 07b6e91..aa1f120 100644 --- a/third_party/boringssl/BUILD.generated.gni +++ b/third_party/boringssl/BUILD.generated.gni
@@ -81,7 +81,6 @@ "src/crypto/cpu-ppc64le.c", "src/crypto/crypto.c", "src/crypto/curve25519/spake25519.c", - "src/crypto/curve25519/x25519-x86_64.c", "src/crypto/dh/check.c", "src/crypto/dh/dh.c", "src/crypto/dh/dh_asn1.c", @@ -344,6 +343,7 @@ "src/ssl/d1_srtp.cc", "src/ssl/dtls_method.cc", "src/ssl/dtls_record.cc", + "src/ssl/handoff.cc", "src/ssl/handshake.cc", "src/ssl/handshake_client.cc", "src/ssl/handshake_server.cc", @@ -462,7 +462,6 @@ "linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S", "linux-x86_64/crypto/fipsmodule/x86_64-mont.S", "linux-x86_64/crypto/fipsmodule/x86_64-mont5.S", - "src/crypto/curve25519/asm/x25519-asm-x86_64.S", ] crypto_sources_mac_x86 = [ @@ -499,7 +498,6 @@ "mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S", "mac-x86_64/crypto/fipsmodule/x86_64-mont.S", "mac-x86_64/crypto/fipsmodule/x86_64-mont5.S", - "src/crypto/curve25519/asm/x25519-asm-x86_64.S", ] crypto_sources_win_x86 = [
diff --git a/third_party/boringssl/crypto_test_data.cc b/third_party/boringssl/crypto_test_data.cc index e1ca010..6ac6ac7 100644 --- a/third_party/boringssl/crypto_test_data.cc +++ b/third_party/boringssl/crypto_test_data.cc
@@ -2492,77 +2492,81 @@ "9643932d01f1f4a2263dca4b9ad26dca1548e4b5b7e27581a63375d0e624f4e4c99b7fb9aeb25307c61142760bc4771e48c7ce38f5eb2408def632096fe40b80d488fe17a455d80edfc1c23c429775b5\n\nSquare = 5ae4e7dc5727543af39ed3d5e9ac086d1a2220421231b82f6f41caee7b9815b4049aea0d43ff499c6c9e1f226f8641351d03f37731c64686d9a9ce68e9234d6a762efcffdecd42f81044111599963d9b6873cc20bf4c8284fae03d2e4f238a14a74df4388fdc80fad0375a5d0d974da7854ede5896ed2ab25d2b49a3c39093600f73120e4fd2faf75381854f6ae80f81b977f62fc72f1fd01c278d183544052b77bd753dd88ffdf5c01745521fb8474b5c23b0b7dc709bafeb91cee0863a0c23ad7192c43cf15fc181d629853cb9b8334082c915dd3d04e3a0a81511d2e84\nA = 2622a7bf45ccd3cd567c757f4c5796b5a0fbca555bd0ac2759c24083172d82d6a887dcf93d9788fde052cb20a8963cb6db22bf5eee6151600f9d1896a7606b11a1b100cbc0925bce037bcea57e361efcc560a9abc495d7f7f45831c6429ac8f979dedc08c304f4da9c0d4d687376d5e\n\nSquare = 473cc933f5a650a4ae358c7f486d325c0e20c83b54838fc08b6ac3ff010f7c4b6a609bdf472974dfc5abda0c6b33c5ec7dc4628d85cb4276108e2b0bc4e19cba135533b3d7bb6a94332aea3165dccb230860d2353166b9905635e606185b014730e9dcf2c433e18cba83859fb2eac4aabef68c8314ef86dec2d534a184ebc4cb193643add0897341690cbe18bc2e775327fd7d71ffc7ebc49bad83cd68394eb276b2e615ec430180303010a454ef73b6a8f02bc48a1fc8a32f8150ef1b733f07da752b8e808000329f4924976bc8b8573927f18ca7c88c210845de6dcd0dee2904\nA = 870b2c4b054076d0d02877b19fe1210a8fad3422b00905a6db748239b8e807716ed9fee0d8c25496593717917edceb5db57f9960bddc1956b6652868d6ace82827bbbada5ae8c15efa26fda22657126c6300906f90e8fabfd58ddf312ce0eee760e0090fac44f00378c676115cd0639be\n\nSquare = b151124402d2f04b0e6599222d380dcf67b9716ef50d2d9ded0b21521b34a7294171f71b41762511b7cca93d9f50e9e30083ef19144882928011dbb143807d1b88c55eea6b19f0c4180023be6da63a59b6bc027aff3f5abe2f65c73b2de1e71c5f4b248bc4547040764e83a860cb3f882bb8b5f7821f92802808fa37c50f2f94d8f56daca841f42d3362762ba843aedbd03d3cdda887f75ba92423965ab4256eb842ad755aa7a2af331b488186f891065b07f5a299c807dc24fc176e085a8024bbbf12f386ef49ccc91bd4ada0936b6de78088cf5952ae6c04f6916799378bc0ede0da4\nA = -35439da9e361700152a35ebdea253378a1febec5f288e5b2bb0bdf25b84751b47e4da5aad7453b70cfd6640d5832237d2115575c738482ac6036c5fc21a981c0a7f979c8d621a92c02166b777475618aa6362a0e225dd6138ead3b2766ed9785ee01e4950a863d2fa0b7f5cb4c9a108bb626\n\nSquare = 4ed7263ae5beb0069f24318b38afe951a5a058a2e960e67f086c9680d0cc6d713f943812070bf94152f7926bdab9e5908941261244542b832f458f05ed5dc048c8b9eb84c2a85efe717e257796b4ca816948a6c8ea209c0675efb2fb5af4622b44e36066593db01b17f4dee21d7c1337ff41436cd0e5a8d01e4030dcd3d49839e59996fbbf1d39bd205343a424f2395b4d3eacdeb9ed3235d8df0dd00a2573260af63db3116a7c65d1dc69684a05caebff34e3d2cba9d4869a953a7b1fce10ebd008cba021008ac3187bba846abd7b39a1b97c9c07d8080549e313dd58b716022de3c1920329\nA = -8e1141dcebae61d5c4d81697f001d792ee2e847c589816f923f0ed42bb4de0d8f911b8ca47ffe77f80b9da6896a9b42f0030a3276218868bbe1a3fa64fb0a577704339af5dd82e66780da6f58900da3f1d75ebfcc302f78ed66ea3c7a737898a29b1f2500686b43bae1e6571addd2842cdce4d\n\nSquare = b09f5e9472cbb75070a67d025957fd5ac3be89c41e4acbcd5f75780ca459562461082c3f19c5a4a416a668b0a55f31f74cf2ec44555ddc43fde64da0ba781adfac4520dd0f78d04d9d2fd33d8b49c72663a6bc845015523e2e4e7ccc69e5b748b8b891e4089420bf0a3f6032602824c7230b5ff95f85a688dcdcfc890af3384710a9fe32ecf9ad7c6cc5761f13079b19d7b2906c7e63c14b64fc88c6f4bd7c41c0356c777d35c3626d49db8cb2d1e89ce682c7fccc3a459b08c20c4e5fc3a8eced9b37d01bed5af6ce9baff0d2b435e6e62871fcb20cf9ec10d1897a5c76e73a441e07fbcc2d9f4e4\nA = 3528e6581de547de385c93ccf1086a17614f23356a918b25bc6d73656a2302b318963bb679c9a93357f4a4f614e74f2e5e88e9c8aed8a6fdd8434630f664ed15ebb6095cbff1593f188a12f4dd6087a85b202f6c24df68ac3b137406c88c5098faf47d1eeec0743b35baaec7dae29b5a44eb09daa\n\nSquare = 5d5dc40783411475a4aac7c1a1eb760f76fcc6ec68dfebb754251cf499870654cd309422935ec841e6be4f5a15078356235c2b8cbe1ae755cd6d814e811072bdb76156b83c7d2064a202ff90af1e0f88f5889e5729a3cffa9faf33c463b74d0ad21fbb4473d4d3ebfa8a52e9c209ded5ce5131b12b69747c365146fa17ee5810e0dbab992f9da28b6c323062484d62472232721d608cdb9b5a341a677e2d7a6e5a983247d9a4001e16687b489b10b18bbf205f982b7ceee27cc3e9c6641827ab7952373f15d36e5f177b82d7eebb3f5054e12cec82c5f520a2675afdec6cbf6235d358c2fe73344002e400\nA = -9a9a19fcdf11bba84b0395088c5d187d84d69b68b77bc6418f63c88bbd8dbbccfe02917d814f9e2241fa0709817a0c85bd554fe887babae7439d96248514c12d71587c906247b3e965e954cdd57f1e51f1979f73c3237509863169efdf281c1359488daad3d9eb990a50ecf4d3fd25d4820077832a0\n\nSquare = a4d69ed4c4c9c08116ec5cc49ad458f0fb2ca00f356aeb148f18037bc49621e14820f325af39f3954bddc9cf01de7ba1e443088545883a94c04ff41a7ed5f65676109c5b711b4115775489667e00aa1b77f6dee5ac5c1789bc71c9fc797abf41c7c5ae3e2c1cf82d5b49b6c0da25190dfa9360b99b2f63444d21ec6114038b8284bf598eed24a2ab2b9802d6edd5b0fdb52f60621a87a14612844ffc71ca98180ff0915cf75f47432f73d28dfd7a932a125095655f07f50722b1673df2cc4f7566a1c6035792ff3f02356b9b9d25e905121df768dc6a1884cf5483eeb813c1c009fe4ed043febd61800ba978a40\nA = -335b12e40bfe0b847ed6ec143490df33d2e64ef4363869cb78dec008cb5cd66ea671dba964a53e48267da288ef4040e06371e1209691b81df02f2c86a79cac85fdcbb6732a1e5309fbbdbcd899fdfed18518d47258c9e63ff7f116ef4a8f5c4867aedd907ccc7d222cf8087afebc108f2a0f197c717198\n\nSquare = 74dcdacc1a4f02a99e3642f54f9d917b117d2ae8d9c392f8b6dee53fac66ebe1680c8e8cc29f5330e0eed3f63d10980060799bc37b34c93dd7b384d4ba30a5b5d42a145acc412ae838d7b9b7137637546d1118f7cf3eadf88b785f0aa01da8638f027c56faa16aba8591b64b45dae6138c9a40309b2ad29c5029a867465f9c6de8fbc5fc4b0442c8a8946272667c7622454ed6f2a236103bed7697dba20db84b5154ff3fbc6b4b9eb67ee43bcaae741d87ee2093ee67defb8eebc4a4a22d97a4e2aa7d4c31a1c88abf4a440ba4e2a5e40c4d903ba5ee4d80b4e8dffb8864bcb9806e015c1ce16490068df87282393111\nA = acf70350e554732c1972903cce269b215e985ecb8d6eeaa67fd5398d0a1b57c0db63368c0f8c2288c3a0466e2b3db081106b90920c46462faf00b5bd654f7140a689b78ef656a26b82af8dd1988f166ea04e9aa777a094d892bc7da4bc7bcf0618526f496cddea6d67df7bb0de9e99a35a0b1b210ff07497\n\nSquare = 9668b9e40a8bdde3c93943a918ca71fa0009cb05a1f592b2bb2c6c6172b2950719bfd80cddaf45d044cbb6aa99715046088f40ec6812945885679231c07f4200023548ead086b834abd8c8f8294db28b203329553242fd2f778ef5cc5ed0b48c7356d8c2d782a01809ccdb6b012896617f11d963300e7bd38ff512829514d94343476818ddf9d712bc70cffe7f767a9fc75a5630e6250ed45e6831b4660eb49d47dd1b8b6a0dddf3fb3ff0e12834337f145f741f70a2aa43769af50f099e004269ac47fab79e060800dc74da88141adbc46c15c7330931e3a2bed9b958f78b30214f81a64d121f96fbcebf7569fec0cdc6b11\nA = 310e7a40667d9d5dc29744b123cdf6a663a1b995f62fa9d4d853cbae0dd23669f4778bb2040317ebf6a06ac6299b21067aece5c5c1afbe6e789d656745ad66464991cada0eb237c6ffe991cac4670bfc90eed5f8c75073f4f846ea244bca0e9502ff56f8e9bc9b6caf275aaef38e26566fef35329ca45392069\n\nSquare = 49e677c8b052b7db97542948542449af47e14248021f8d3d3f92b9af41c803072f71050f16dd848aebb270affc47e85427a7c73f227f0d63f140d0d293157af0d972eb5b38de494fbc78ad3a4c3d1ab40197bc4427752b6102d1ced6d6cbc9d7caa0d1bcc57e708535822180055ecc9d9667e0590274b778480a3720823e931ff6daef358b1a1a9092f1f05fbb5b10ad5707a124e8be63bc696f083eb74e5b4f0e3110de8f297ecd30dfd2bcb010dcad4e387520d3d00365fc51c2a3dfe064b1ac77a9295f66beffbe5dd4333e5cd823b0f36b0b94d66507b1d9381060980f62f38a62e38e5a75203233bb8d64089bfd100f3205f1\nA = 898b5f3655de74cec3b0fde2ab03fd18cdbcfc3eeea48ba39317d26917130c2b78e05237cb0454ece268f091cab699fbcd51ce341b53d6ec0cda5d0d5388bac25c6517214a39d03450ef8502e1675bfe8e57bb6086f10ce4cf8ce65eadc865b5bd8a00dc26394f3adb2ace609149e3582cf44246184b2adc0ffd9\n\nSquare = ad00f10fed55175159b2409dc80899f9113ba7c8099d0402ec0f520ab4aeeb46d36369494a4e6fa23675adb38148fd2efa082df5094c0acfb77a9ab6ba7a299298d69b04b58011c35325f46b765e580b5c05eca721904f1fcc355dbe39faa92af5c9a6dbc4ab80e62b815b45983d9506ebd52b9efa7a6b9da352d1e4fd6ffa81d3b4596a0c14fb825297da361461ff2240e4378340d2ae529932d78f3d9f6b3c6d65d717e66122e5f590c50ce0a5d81ad8e0f24e104c0913cd8d0eb2de4c8cf62a7535bab5502df3fba08bb4dfe73d89c8b00edaa7d5f3274be9959e7ab6b6dde54f2491728a1dc11fa8e1c6a95e67eb7617e9b7471ee40\nA = -349cc2a5658fdbe9ba5c350d3b25baa38b1ede01926694bd550d36883e53d8758e8f1ebe83e2f4560605510413a7d880929e2d9cbc2730b1736dc2689cf7bbcdc68a342b6398e547a9bd67cabe298796d76b98ed4c1dd9c22e36145892e8fcf2258529aed24252a70b6ca8fd2aad8a84becf7e1bf98b1e9bb024b8a8\n\nSquare = daa3835d3189ec9ade592e6076e76d441838077a9431273bdec02379b3a6ac38aecbbd57c3755ea58d", "def8105ac28f2ecc8598ec0c4bfc9c1c80222fffc776722eb0621cdd8a0d55f08767fc2922282a76e529d81e4d6e21a2542b8c9a403709ed1132e3b52786b81e684591438fdddb5df2f0b72e6b39cd2db6c0cc55c759c2dc1b6ccc20a5cfd10c6fd345fc766035c7478570d4ac534db3fdb718e2bdad3d096b137bfc09a562043800957e2afe4fdcfe292881f6189edfce52370c0438c2822ce3b14d73b3eff32f7e5ca97e989326b4e3a8fa35544193f8590bbb0ddb1f914894ab87998090771a0be1fd23917cd792be86ea0b98e6eb24\nA = -ec953f1b7ba7d561edaaa23076987daf86f50e9a66c36f0993290549a9006dd9d424885c0fa77295cfe34fc81c5edce9e2371b3039ea18d8f998d1956196284e6d81eb1c62ecaa8cf3fcaca28ca7e64342803c8dc3c139080bdd4a1ff30d7288b085a579d9e90903bd363b48f2072bb6fbfbd9ba2cab30a8a63784d246\n\nSquare = b33f4f3ae453058f4e865ec78f0844bab7af66a97dc2f265ca73ae2232777474bfdda39e10652d7386c16f145272192af728893c3d8a8e92c60d77722b924c30269ff5a399a2449ce15e50320c528c22655ad06227ac4efe5a993179ec61c2fc9115f89d75b53961fd16f7797657f6fbf55662b019608a1d30f64a2c0838e0018b7526921fdd34fd462bfcb2462b7065e2bc7abd57d71371e45dfd8fcfcc00a71f7e45430820747c9a060b72e4f6d2919cbffd00beb0c31a2bdc32afe2cc540b38dd04a2b73ae5ba481a6e535f37a757bbd6aaa972986213afadfa47cb7a15a6f1d443f93cb0ed824a10b4b7d82cae524a096b65ccb39be3c37c07f59\nA = 358da59ef65f62f633675764e292e5a68879df24a4727eca1fc4d232b3a6d936976c92eeb11456b5e8c11319838c145c6529d2f3acc828e55b8274bfe9afb5db241b102715f8e8164e454ef39f13ff1b37cf367a5a66c4f743c750896b7c3c29026e448bb36c6c06b0d9a3d048086ef0c3cd922a02e794223f388b5d646db\n\nSquare = cd4246489f6f221f920acbd8bdcdd17f47d2b77268f72254de4190685c123e8c5eab8517fded1852e8316c9e549d3fa355142d91b2921a3c94aafd8862cd2235429340da38a2af131b8d002f17662354f5805f6a7af7afb6dbd2f641036600614cea42bd8b24d86a5109eed29c0865a5f30c5291b1d1ef3223f9b9826dee773d98ce972da92daa19e843f84ca5f1cd77925a3c1117242ab0fb509b94a83f8de4fc8d21f856f37a4d025b3024bd0dbb6d8acfda4ab2993fd6eb7a7448d4f66ec725d37f0eb14eb242c0ff3f0c4572ba6b98a4ce905fe1b7ca3daca56c225171428c56af938fb66b37e99e54139157bbf41f536989ef813af738837afcd62290\nA = -e53ad05c88568f09f616797f0b7f2756fb543d691ec2a5b645c1e5892a247302826419a35b1348cfd2c1c569c23c31b4c46d6c57d4a488c29ab5beb77904d4adfcd0a01ea0a26bb0cc8790441cc2c8c900f030d7315b4319f1a3cf5685a140e03abe6b94730ad79e8de1f4a0cded86a3d6cfe2db267fa7dc9b2bb32872a90cc\n\nSquare = eea8028b26e0df090504d54da714a6f5f2695202e53cff479c78aedd47a8dc676243ec586740fde53b3eca9ca02b91031ce766242184109503fbe25b1b6d318e3cd5970fabd16dfa22984dd2e9f1e0f14c189170fc69c031d66663703e6235a942d51a4545bd7b0769d01d302ce2b00b83f01568a1e378f61fd0ca6201b0490330580cd9de85719e174a71915d7efbf65cd73d8f4e66f27e0dd3144d58ec09ed0f7ed7d1238ee596922807100fb7a11127944ddcdec6a9ca3bbf6df7301e354f3f049bfb7c275b43c3d8cda5907a932fba507c9145ea3166081c1b48fcc710ee32cd931f936c796b14f8a78a592e67753a7c9e428a01719c8ba82652f3a89fae110\nA = -3dcb44be1e54c5a5d7db48055ca9afa1ebe2ae648aa6e16ac497502a7deee09ffa124720fad0ab163ce8b3ea6a90f110ea52b67dbc424d0cf1e8c9726dfd9e45bebcefaa5cd5706edeed27896525f31c6bbea3d67ee97badefabf3e2532470b66e3ae3100f66ddf50cf02fc3a8e3f44c304251d3b6a7ca3a6e4bd5d16a41bd97a4\n\nSquare = 0\nA = 0\n\nSquare = 1\nA = 1\n\n\n# Product tests.\n#\n# These test vectors satisfy A * B = Product.\n\nProduct = 5befab3320f8f90542f3120235abd926aac3805a19e343f690\nA = b057af553afb120db6b7764f8\nB = 857734c4c27a1d17f7cf59dee\n\nProduct = -ab1ce167f4b2945c55ae3f87df50ad07d4be87cf9f8aa07b0c\nA = ae7a6a87ea8981a567d0b3ecc\nB = -fb0fed5f8c737bcacef4d6cb1\n\nProduct = -c2606cd48e6b075c8da79eb4668e7157f1f175c2860fd4c475\nA = -c28dc31984d4583e9d45424c3\nB = ffc4581a5c3f885cf42767e67\n\nProduct = aa6805b5408aff7f914472756da07830dcad902834dbdd6944\nA = -ffa07ff9f503511954e5dd3f9\nB = -aaa7af472ad8957763f5a7c64\n\nProduct = 58ca2569173389df29b5ce4b784086055dee821a7243db7210\nA = af417d936f4690008811a1ae8\nB = 81b26b80b43aa65aa55ded52a\n\nProduct = -a043d31dfce8bd01724d31c863d0a64f1bf013509d77737c42\nA = fb5fae5edefb6997d44a1ecd6\nB = -a336e50c6f7845a1686cc88a3\n\nProduct = -b5d6a45ffce851b201239d938ba551bab7dcb59fc11fc35fce\nA = -f918faa58bb57a2ffb8b01f05\nB = bae08c3006fade695029a1df6\n\nProduct = 6f2fde7d1a18625d727c6345ed85e597d546d9228bf7f0564a\nA = -8d108d7a16f0696d4ceb24445\nB = -c9c764cae465207097ef8d2c2\n\nProduct = 93808b1140841dc9735cd61c6f855ddbbb83066689b0d7e1a0\nA = b386d08daf3fa2154e9c768d6\nB = d2557dceb2d02d04d9c578670\n\nProduct = -ad04212ca8cadb1f7861c5130ba3a747046a2a7e4a0c72b69a\nA = e4e5f7d1311e0c5f2e404d55b\nB = -c18057a328d8c7375afdfd4ee\n\nProduct = -685e75c232f2b4a0e455fe5ee8aea52f292ad8b8178320e692\nA = -a683312f132b2320632e74ef6\nB = a0758f12791453b4af354730b\n\nProduct = 6f588c53185c503dc5b0dc3002d3817ca2e7eb2370b3e9a647\nA = -d70c9b93170261091f0c53f27\nB = -848c86c51a186ac4c9080d3e1\n\nProduct = 5e3bc5a04e054a9a244bf7c86cae215072fdb70e9199989427\nA = 898b64ef09d7cf63966e1a3b5\nB = af638b12f26aa5d12e97439eb\n\nProduct = -8d8372b235b16108285203c03a8aef6fdd3c0e1a9fd31d4f68\nA = f6003dc83818c14fbe36c9998\nB = -9343f6cbcc81fa4c9399dce5f\n\nProduct = -5ee6509abeeb7af7fc5caef40d1822ad3150c8d74f522dc7c8\nA = -875ff6f56ca72cbdf614bb9ca\nB = b375a68a21dfb1f159c22fa14\n\nProduct = ada25be404a17385af5a330da799e5909da81bfa0715baa6f4\nA = -c9b8df392e76abc3eb7d5ce04\nB = -dc5ab818c70594dd917b4243d\n\nProduct = bb24422ee4656ddfcd50ec38201b15baf679d3b75e5cb878ca\nA = f8e12cf4defe388b78510f687\nB = c07ee817b4ae95c2915b88966\n\nProduct = -93da296ba164c7220a17330647aef0980c94eddd2cfa2a3b2d\nA = bc5dc74ddf7a1363d1c2b1f25\nB = -c8f069bad7f93cbfe6df51169\n\nProduct = -6b2e1d132c4e0b0dc9b7e7de7d424fda5180480cb5ff47c755\nA = -a8048acb66a8bb88df39266e7\nB = a34e0b265d71435ae8c92a463\n\nProduct = 6ccb2cd93783576a8602ae43f41c786008b6623a4cca0a010a\nA = -b071f1f54790c951c1dd2a1cf\nB = -9dd89bb4d9b546207e282e2d6\n\nProduct = 5c742ba47d0d64bd97509927ce957deedb855766cc24c60016\nA = b44f3f252c368096fa62747f2\nB = 83439b97dbac579fa4f7b7d23\n\nProduct = -7347ba65691c913286c2fb55e45b177f031c1d86ae0e9f654f\nA = 937cf0643ffa53cdea24d642f\nB = -c81881f78243dd5737a7d28e1\n\nProduct = -9bc0649a703674e59f83ff9b8a560e5cbf51f65ca310f80f95\nA = -b536f8d9769be6f62da941ae5\nB = dc0746fb101881ae0cacde6f1\n\nProduct = bf4992fc3a124de350f9fb90ea825cf663b1fa051282ef22e2\nA = -ff7eacc7de1bb01d668c693aa\nB = -bfaa6627f9fc7ba68ae41bb2d\n\nProduct = 7c8992d34cc0b63f1c953f68d4e12a99d3f3a34d16bd76caa9\nA = 9e0d5a850d078890a983c0ec9\nB = c9b72c118b3e1f1023a696ce1\n\nProduct = -a75840c95082b9a0ae0d6e0a4eb5e09288e4e2a66e9697d9cd\nA = b2b042a21045a74ef1a5091d9\nB = -efbf8b120b384e869692a1b15\n\nProduct = -a510b333bdb4ed7479c142e8fbe2b12f7671a42acbe16c0998\nA = -e7fd5e0bb5496b9d876c27f65\nB = b6262653b2be44501af1d85b8\n\nProduct = a1c1e90afc4684754155526e307fc6ed798746f347bae2c880\nA = -b84674832b26ded0a690a8ff0\nB = -e0b7bdf2fd05a038ed3640b78\n\nProduct = 5588e0c33bffbefcc5695ca0615abd383343f21a8a0d22b222\nA = 80cad81ad9a66ab6a1c2e5669\nB = aa0453a77c8af1584f54750d2\n\nProduct = -6460c2fcd6cf3304ab163ea883ac48e2031cd10f2e9014c0ab\nA = c49ad3d7c8848d4fbf913b10b\nB = -82b3dedbe3cc7cd532ad632e1\n\nProduct = -a18717330b711669e85abde8c4dce426529aa621ba3da2a477\nA = -cab4a9c0a331a5a5e826dda1f\nB = cbfee5041c13075dfe3399aa9\n\nProduct = 8ab6282ee892b53c083d319a9dcab48af97a1ac8493c0bfcad\nA = -f7d13e47f9aaac8c25f9bf75b\nB = -8f4aa95231c1e2336aa092297\n\nProduct = 8f2d1c23c78777ed371f13155445ca3c88cbc0a9b299bdf9d3\nA = 9d8248d00defce1ad081337c3\nB = e8b479295ecd9cef7301f24b1\n\nProduct = -86d5e0c5b581fe59819730b4b71e33d1f85f9ab504c7dbe2d6\nA = b21b45e88acff48562a19729a\nB = -c1cdfebccc763beeac394b997\n\nProduct = -484ca05aefa113bdfcb1bc623f730c9f9555b462a8ab4c9606\nA = -8c12b406c02c4417163c0956b\nB = 8422b15c80c1c087b17eedd92\n\nProduct = 614c3c91f60050c785fd229a3ad74674577a90cacb654e0a5c\nA = -93d45bce155a23a397506d96a\nB = -a87e339c3fd5aebede5fb1b36\n\nProduct = 9683285f194a7e4feeab196a36bdfc4f828035fd184b9cc692\nA = f196d8fe760fdcae7eb60e2f7\nB = 9f7d88a2163ad818bf3a6377e\n\nProduct = -988a64599c19cc64f3cadc1a83fea6550185f6cc3ab82af822\nA = d0584b2a306671e4d2c9d0c7b\nB = -bb6e7559df199c68d6df3a3c6\n\nProduct = -68456814cb0edd951196d04c853172afdd5787a5bd69a57876\nA = -cefce1b0a1fb22862418bb597\nB = 80f614139947aea5e76cd55fa\n\nProduct = b4b1cbf5d6566e7a57aee0cc5c9c8ec4ad885e8766aa7662a4\nA = -d68ed1bea046c6cad057e21db\nB = -d7988b9be54f6e332d019032c\n\nProduct = 6b09212675ff5257a1384371e17b37dcc268bbb141577902e4\nA = a8208053adc20a609d5d01404\nB = a2fa927c5458c4fe662d7a3b9\n\nProdu", "ct = -8361bc26f9bcf55f677e047d822d3004027da0d0455b244d10\nA = e82b6410b29020c2d6810a977\nB = -90ddfe0e7f0d6b9cdc0815f70\n\nProduct = -f1b6da00923fd513a83e32040a515649fbd362f69ebc016d9f\nA = -f9b697d9ec774a8d1ee5ea905\nB = f7ccb46a8869cb028492bed53\n\nProduct = d06206963f2e150bacdb32c823c3a47f013d5a267c3c0d0c88\nA = -ea8e63afa99c719897ad7f2ab\nB = -e36f11f55b6148d1b4f46e598\n\nProduct = af774a5eae6084df5ca499ef005642730adabf6a4f9533e2fd\nA = e4c7af7eea3ec9cc2443b7319\nB = c457bc264c8461789931baf85\n\nProduct = -76350f428bfbb95e6c253ec0f457aa84cebe8c7cb1af2a2120\nA = 8fd1ff97465775d44dee58ae0\nB = -d268a7d328f44baf80e35119f\n\nProduct = -787ae3f114f9a8dd4d249d5d3f3b0897b02564b9469416cefe\nA = -bc0b398bd0ec045b0cf147b7e\nB = a4050955c234e473257d0c641\n\nProduct = 9d6320b3d4aabac097a079b9bd2aca7f1898bcab0f23409fd0\nA = -9d7a4ebac630cc0662b816fb5\nB = -ffda517d3eb3214986b04e290\n\nProduct = 80bab8bd800ac8c9dc3bb57dca306f10af6fd88c5d8314833c\nA = 834bc50140d6c6ab938dc58b6\nB = fafee47793cbc533b3c66af3a\n\nProduct = -b08920f5922226b1dec87151ae087d8a7e5c1aea8c9be148b6\nA = bfd5b1ad323c79428cb2db36a\nB = -eb956a10edebdd658e6810fcf\n\nProduct = -6d428e08e8350bb4b0fae3b662c82df2aef7beadaa17430dbb\nA = -a57da276998c548101f514e9f\nB = a9040c1909712e1149d295765\n\nProduct = a57da276998c548101f514e9f\nA = -a57da276998c548101f514e9f\nB = -1\n\nProduct = 14afb44ed3318a90203ea29d3e\nA = a57da276998c548101f514e9f\nB = 2\n\nProduct = -295f689da6631520407d453a7c\nA = a57da276998c548101f514e9f\nB = -4\n\nProduct = -867614005cc204a8d19720fe13\nA = -a57da276998c548101f514e9f\nB = d\n\nProduct = 12bf3b676f64e5929d38c35e803\nA = -a57da276998c548101f514e9f\nB = -1d\n\nProduct = 24d8f92c68303ed0b96f91a8167\nA = a57da276998c548101f514e9f\nB = 39\n\nProduct = -49b1f258d0607da172df23502ce\nA = a57da276998c548101f514e9f\nB = -72\n\nProduct = -6fd5e6ca25c3d51b2e529f22173\nA = -a57da276998c548101f514e9f\nB = ad\n\nProduct = 1276d4705b81b82da4c7e82559d7\nA = -a57da276998c548101f514e9f\nB = -1c9\n\nProduct = 1ddb9abfc5d4017f068a67b5f4fd\nA = a57da276998c548101f514e9f\nB = 2e3\n\nProduct = -3a8b41c914b1b4a4e341433601f7\nA = a57da276998c548101f514e9f\nB = -5a9\n\nProduct = -97c0f4ba414d6e7d4c8b7ced84d4\nA = -a57da276998c548101f514e9f\nB = eac\n\nProduct = 1198739e0c23639c176d46d13f7c8\nA = -a57da276998c548101f514e9f\nB = -1b38\n\nProduct = 159150954ee0dedf541e4dbac0ec3\nA = a57da276998c548101f514e9f\nB = 215d\n\nProduct = -441d4bc44c86f02ff12c3d91a1562\nA = a57da276998c548101f514e9f\nB = -695e\n\nProduct = -64726b76005ebee27592237ba5dde\nA = -a57da276998c548101f514e9f\nB = 9b62\n\nProduct = bbe4ec7cf7c5bbd198e0ea86bb658\nA = -a57da276998c548101f514e9f\nB = -122a8\n\nProduct = 21f717d05681fd2eb1796776a69ef7\nA = a57da276998c548101f514e9f\nB = 348a9\n\nProduct = -396ac788a1748bc6955f99be4d2c64\nA = a57da276998c548101f514e9f\nB = -58d1c\n\nProduct = -54a213eb083aed1a04f3d1b2da62e7\nA = -a57da276998c548101f514e9f\nB = 82eb9\n\nProduct = 1366fb9c20fb14b8b9a9be4b3e3dde1\nA = -a57da276998c548101f514e9f\nB = -1e037f\n\nProduct = 238d65fd26da4733e5d93ab2485d40b\nA = a57da276998c548101f514e9f\nB = 36ff15\n\nProduct = -38272a99be154d531e922be405aee9a\nA = a57da276998c548101f514e9f\nB = -56dd26\n\nProduct = -64651b62b6a454c08951632c7f2c398\nA = -a57da276998c548101f514e9f\nB = 9b4d68\n\nProduct = fb272e3597b816144f8b945ae6130e0\nA = -a57da276998c548101f514e9f\nB = -1848320\n\nProduct = 280d9f5ed7243712ecb9a7c6358bcb8b\nA = a57da276998c548101f514e9f\nB = 3df5795\n\nProduct = -2fbb6bb8e1ba78cefc47fbbc20e188ee\nA = a57da276998c548101f514e9f\nB = -49d6652\n\nProduct = -57f29c13691ffa1642d2860dab9d288e\nA = -a57da276998c548101f514e9f\nB = 880c2b2\n\nProduct = 139c19d7668e6aabf2d7206cb0723ed34\nA = -a57da276998c548101f514e9f\nB = -1e55aa4c\n\nProduct = 2950ce04bf0cf836d4fe94b88fb757d0a\nA = a57da276998c548101f514e9f\nB = 3fe968b6\n\nProduct = -5175239488dad05a58414251496d2a06c\nA = a57da276998c548101f514e9f\nB = -7e020414\n\nProduct = -945ff0ed38bc6020cf679cbd3e0758c6d\nA = -a57da276998c548101f514e9f\nB = e585e573\n\nProduct = 11c69ae98f6b27e95477986f796bc67c8c\nA = -a57da276998c548101f514e9f\nB = -1b7f653f4\n\nProduct = 209afe75e8fb5ac76d13c06b545f5d4d73\nA = a57da276998c548101f514e9f\nB = 3270154ad\n\nProduct = -386d64b215e41506514f4988ed237e4da2\nA = a57da276998c548101f514e9f\nB = -5749c891e\n\nProduct = -6c13cccdb1d140d0babd52707ea72fa278\nA = -a57da276998c548101f514e9f\nB = a72fb6288\n\nProduct = 136228a8a45540372b9b3cd7f82021f6546\nA = -a57da276998c548101f514e9f\nB = -1dfc08a2fa\n\nProduct = 1f0ad3babf9d132eaa08cf5cdb8f19dbf01\nA = a57da276998c548101f514e9f\nB = 30050f2e5f\n\nProduct = -50d615ce183258e95af77319b766fac81e2\nA = a57da276998c548101f514e9f\nB = -7d0bf92cde\n\nProduct = -817d358293b86a56a4e881e50257c549471\nA = -a57da276998c548101f514e9f\nB = c84efb12ef\n\nProduct = f09b9e80be251de474d726b16e25a6865fc\nA = -a57da276998c548101f514e9f\nB = -1743322a484\n\nProduct = 22996cb0f9c60e35dce49f3825f8a479db26\nA = a57da276998c548101f514e9f\nB = 3585acec11a\n\nProduct = -2b307a37c91791a61c0691858f5f783e4678\nA = a57da276998c548101f514e9f\nB = -42cf6be3e88\n\nProduct = -8826698fcba6c30d755fc523de1cc25301ae\nA = -a57da276998c548101f514e9f\nB = d29cc8af592\n\nProduct = ae37fc99fd419809310782714530d7428d77\nA = -a57da276998c548101f514e9f\nB = -10d8059d4a29\n\nProduct = 1d544a20f9bc7d95ab67d1f65743979f23bba\nA = a57da276998c548101f514e9f\nB = 2d5eadef1c06\n\nProduct = -367897184e9929a0294d320f10278889fbeb7\nA = a57da276998c548101f514e9f\nB = -54431582d0e9\n\nProduct = -943a509076a00060a2e7fa1cddb7468d734a1\nA = -a57da276998c548101f514e9f\nB = e54bb102f4bf\n\nProduct = fcce6e42879af5ad13545c0bcaab85b690cea\nA = -a57da276998c548101f514e9f\nB = -18711db522cd6\n\nProduct = 258c49f86d0cbb14ae9edbd3456be8cede2022\nA = a57da276998c548101f514e9f\nB = 3a1562c7c269e\n\nProduct = -4a8bbce59ad7daa51136d557f7fa16e9a2faad\nA = a57da276998c548101f514e9f\nB = -7350e780b0f33\n\nProduct = -82f53ec9333275d5cc271876a7db936db49280\nA = -a57da276998c548101f514e9f\nB = ca94ad312dd80\n\nProduct = 11daee4fcc713db5b2806e47fa5dff3b5b770eb\nA = -a57da276998c548101f514e9f\nB = -1b9ed6758f9635\n\nProduct = 17038cac4f0c94dc24985ea108ae6682e175752\nA = a57da276998c548101f514e9f\nB = 2399b8a9b1116e\n\nProduct = -37e5f14394bf347a3ed061769fe8e6424af4348\nA = a57da276998c548101f514e9f\nB = -567840a7569fb8\n\nProduct = -9253d4a32a88d8f725984514d969012ead7cc9a\nA = -a57da276998c548101f514e9f\nB = e25b246f733f26\n\nProduct = ace3648371c16a931d29004e79f5b9678391da5\nA = -a57da276998c548101f514e9f\nB = -10b717b27b6a13b\n\nProduct = 1faa5b45d04c143c339b09d3aad94d39b94ef960\nA = a57da276998c548101f514e9f\nB = 30fbd672e106aa0\n\nProduct = -3fdfe246d27aae0d08d63b2bc501461d2bff3b8d\nA = a57da276998c548101f514e9f\nB = -62cef5f078a8253\n\nProduct = -5b792bfaeff04ee3d948cb343a249d49eb344f57\nA = -a57da276998c548101f514e9f\nB = 8d805ac65649c49\n\nProduct = c5f824406161eec321da5a58e3e00d393b55abe9\nA = -a57da276998c548101f514e9f\nB = -1323dd41d2e1e077\n\nProduct = 2226dec8a57be8e84e42559007e2d101ccbe67f8d\nA = a57da276998c548101f514e9f\nB = 34d47842b5d0be53\n\nProduct = -340f50f812c7420b502000940788a700f6769788a\nA = a57da276998c548101f514e9f\nB = -508836d8e1193d36\n\nProduct = -a00f1d96e19c590479625c5329a87774b5964cc78\nA = -a57da276998c548101f514e9f\nB = f798fc858657f888\n\nProduct = cb94f830cba8997331912a6a31c34f1bef826d121\nA = -a57da276998c548101f514e9f\nB = -13aec7a5c52a0883f\n\nProduct = 16b45140b048d6dc0b9fc811df7ce7dd88357fff04\nA = a57da276998c548101f514e9f\nB = 231f27f3e347bd67c\n\nProduct = -2aa94179351b4e87de5849ab619d94f47450640199\nA = a57da276998c548101f514e9f\nB = -41fe3ec2189599cc7\n\nProduct = -5489401d3da93158d4284e557d74016c0a7cfd935a\nA = -a57da276998c548101f514e9f\nB = 82c5281df41bfc066\n\nProduct = ae04d5b212ecfc9a6d7df07794d565df52991fb70e\nA = -a57da276998c548101f514e9f\nB = -10d3139229f5d02432\n\nProduct = 27821bc811f45d63089790b41d307be978d4b19564c\nA = a57da276998c548101f514e9f\nB = 3d1da85cc012b3e234\n\nProduct = -3de3c9e9d7fa3020a578706339314890dccf63096c2\nA = a57da276998c548101f514e9f\nB = -5fbcfb28bfc9044bfe\n\nProduct = -627dcb299a6720044abcf11469bdfd3f951edbb5bf7\nA = -a57da276998c548101f514e9f\nB = 985b930517b78e6ba9\n\nProduct = cc0622441497a37fddf1856d5e2c99df52b99ea4573\nA = -a57da276998c548101f514e9f\nB = -13b9b88948fb7e95cad\n\nProduct = 1a5168e1a492210591ad1ed660adde9110390e4caf32\nA = a57da276998c548101f514e9f\nB = 28b631c6e04b6ab0d8e\n\nProduct = -4d8ec27b7460ce616421b9f5cae708c2ac241daa59b4\nA = a57da276998c548101f514e9f\nB = ", - "-77f99bdf1eb09da6dcc\n\nProduct = -55afd796db7bce822a00073fc8926d3bd0c79772f036\nA = -a57da276998c548101f514e9f\nB = 848cdd6212b9bb3620a\n\nProduct = dc494b0d73e8ec07cd2bb6dd8191d2b4d48e7700cc34\nA = -a57da276998c548101f514e9f\nB = -154c39567bd8be5f6b4c\n\nProduct = 240e9301b4345b914ecd91a49a0e651524dcecb6fdc6c\nA = a57da276998c548101f514e9f\nB = 37c6e7ee89cf87674814\n\nProduct = -39002ecfd6d96661b336157ccef6536756ad2e9219be3\nA = a57da276998c548101f514e9f\nB = -582cdab09915a652203d\n\nProduct = -695f49fc891d53f396f0593efae3973082b76d4f9e944\nA = -a57da276998c548101f514e9f\nB = a30074dbce2246af043c\n\nProduct = bba2b7b45b97cb0d7fb30fed95089870742ad69e7aed7\nA = -a57da276998c548101f514e9f\nB = -1224195afc7b394ae8cc9\n\nProduct = 1910edc278515ab7d4cc09b496dc3c06c32c75bc7368af\nA = a57da276998c548101f514e9f\nB = 26c6701c39334169e7bf1\n\nProduct = -3670b7f9b661aba35ce50984d83173c84c8fa60e04d100\nA = a57da276998c548101f514e9f\nB = -5436e84b4a29858a68f00\n\nProduct = -7fa0d3e0082b37475342b7e22e5dbad7b8d4cb5d64f871\nA = -a57da276998c548101f514e9f\nB = c56e0f44fc63bca242eef\n\nProduct = da7fe3367ce640fa5941c033ac1874312f10ba5950da75\nA = -a57da276998c548101f514e9f\nB = -15200043166ff309f0426b\n\nProduct = 1871d72481f66b1d413100edd6b339cbbaa67b3b2b3cd57\nA = a57da276998c548101f514e9f\nB = 25d057879db26fa29a5e49\n\nProduct = -3cf1dd1e2df3456757d72f35353c3c7a659b2ef844ad857\nA = a57da276998c548101f514e9f\nB = -5e46be70de21949df67349\n\nProduct = -5e861cbe47aefab2a7ea59292aab1258932b9a322f66e63\nA = -a57da276998c548101f514e9f\nB = 9238670897685a6c9cbdbd\n\nProduct = f623344788efb857db55c924e95a437effa4dc8bb2bcd24\nA = -a57da276998c548101f514e9f\nB = -17cc0ec84c228225a7cf45c\n\nProduct = 15514c916b0ae7cde6add16c629d3e19ba52a101d75dff72\nA = a57da276998c548101f514e9f\nB = 20f9f925b3ed307edbb154e\n\nProduct = -460cf5b14f9d0b547c3084bf44207bf881745c409b08d07f\nA = a57da276998c548101f514e9f\nB = -6c5cbfd29f3dae1dce99221\n\nProduct = -5ddf7fb91d765af97dfda5333d8779e80837c2b51cfb4f43\nA = -a57da276998c548101f514e9f\nB = 9136aa79080defd1bcf90dd\n\nProduct = 12c1a0edfb6ab6a0caae2553fb3743827e1470a8954e0a3fd\nA = -a57da276998c548101f514e9f\nB = -1d03b512470dc3052779f3e3\n\nProduct = 28388a244214abf046488a8d95308d95f021eae4b994a5a52\nA = a57da276998c548101f514e9f\nB = 3e37dce784274962ff862e6e\n\nProduct = -4da476e76119deef291c0f56934a912a0877278a19a561ee0\nA = a57da276998c548101f514e9f\nB = -781b2f2dc40094a7f8fed520\n\nProduct = -5792496d33dd45e225f9dfca17419a04e075ffc0c90b37b82\nA = -a57da276998c548101f514e9f\nB = 87772a4fb582acafd3e4ef3e\n\nProduct = dd3a3506a7d748de16fb43d666928a87de0354d8e8a1bcaaa\nA = -a57da276998c548101f514e9f\nB = -1563841bf7851ff158a395716\n\nProduct = 24e8fb09a9ab0808ff643122479dea5ed41060c6c5b74e8752\nA = a57da276998c548101f514e9f\nB = 3918c30b5568318a58e9be16e\n\nProduct = -366c125f96b38b58d01c939c27c4100af3377eabb792b5491a\nA = a57da276998c548101f514e9f\nB = -542fb814f45924aa09a16f2a6\n\nProduct = 0\nA = 0\nB = 542fb814f45924aa09a16f2a6\n\nProduct = 0\nA = 542fb814f45924aa09a16f2a6\nB = 0\n\nProduct = 542fb814f45924aa09a16f2a6\nA = 1\nB = 542fb814f45924aa09a16f2a6\n\nProduct = 542fb814f45924aa09a16f2a6\nA = 542fb814f45924aa09a16f2a6\nB = 1\n\n\n# Quotient tests.\n#\n# These test vectors satisfy Quotient = A / B, rounded towards zero, and\n# Remainder = A - B * Quotient.\n\nQuotient = 1\nRemainder = 0\nA = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c\nB = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c\n\nQuotient = -2\nRemainder = 1\nA = 107f0e6cebfe22ac11294a06fed2b994d01c9b3610d50bdd254adafd08c93be8ebdd1e85e1286fe9c9e682a90cbbd6351681b\nB = -83f873675ff11560894a5037f695cca680e4d9b086a85ee92a56d7e84649df475ee8f42f09437f4e4f34154865deb1a8b40d\n\nQuotient = -4\nRemainder = -2\nA = -3d8746ae2123c2d3f1d35910b42af1f86f5e81f8e98986cea20b2a1bdb8af6cf111f1258f112c837accdf4868463fe9eba536\nB = f61d1ab8848f0b4fc74d6442d0abc7e1bd7a07e3a6261b3a882ca86f6e2bdb3c447c4963c44b20deb337d21a118ffa7ae94d\n\nQuotient = 8\nRemainder = -3\nA = -5645d65662eaac73050de06f8f982a9b2ae680467712284be3e2b0e58ef4bf4d72b5be5e12ee1fd803b47f161759662ff5c4b\nB = -ac8bacacc5d558e60a1bc0df1f30553655cd008cee245097c7c561cb1de97e9ae56b7cbc25dc3fb00768fe2c2eb2cc5feb89\n\nQuotient = 10\nRemainder = 4\nA = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b4\nB = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b\n\nQuotient = -20\nRemainder = 5\nA = 12805392c55ffa0e27e85e15f2b339872793664e9ed3074cd2600aa52459a57197130d1ea46775ef43115c9413248cc7b34805\nB = -94029c962affd0713f42f0af9599cc393c9b3274f6983a669300552922cd2b8cb89868f5233baf7a188ae4a09924663d9a40\n\nQuotient = -40\nRemainder = -6\nA = -3579fc4d6083394c691b060cf9e20318fe17da0487337f76710bd11512578830ba94ac7b587a2d5ab7cb4afe611e349cdcfb86\nB = d5e7f135820ce531a46c1833e7880c63f85f68121ccdfdd9c42f4454495e20c2ea52b1ed61e8b56adf2d2bf98478d27373ee\n\nQuotient = 80\nRemainder = -7\nA = -74ebad4b39ebaaff82cd91082408c979527907c363d8f0f75db410523f8477c074c45ff85851b6275b1ebc5279029818e78d87\nB = -e9d75a9673d755ff059b2210481192f2a4f20f86c7b1e1eebb6820a47f08ef80e988bff0b0a36c4eb63d78a4f2053031cf1b\n\nQuotient = 100\nRemainder = 8\nA = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c08\nB = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c\n\nQuotient = -200\nRemainder = 9\nA = 1bf534da2f4365c96fc5dd4928e73ac24b157b5136ead90cf6596033ec387a2c14bca828000ae1725f3a5ace8ad67a8c07a0a09\nB = -dfa9a6d17a1b2e4b7e2eea494739d61258abda89b756c867b2cb019f61c3d160a5e5414000570b92f9d2d67456b3d4603d05\n\nQuotient = -400\nRemainder = -a\nA = -3a172cc9483774544311a1366659d9e61cc9fac7dc11c68e36aa991ef4d5e96becf5bac3e0967c904d926617ea11bb9551b980a\nB = e85cb32520ddd1510c4684d9996767987327eb1f70471a38daaa647bd357a5afb3d6eb0f8259f2413649985fa846ee5546e6\n\nQuotient = 800\nRemainder = -b\nA = -5ecff3a3e47fa615b6e3ce2dedfdeefbfe1d437c394631820968a9650b59dc3a2dd1c9a0b06537e4e5c408a59e580921503580b\nB = -bd9fe747c8ff4c2b6dc79c5bdbfbddf7fc3a86f8728c630412d152ca16b3b8745ba3934160ca6fc9cb88114b3cb01242a06b\n\nQuotient = 1000\nRemainder = c\nA = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae00c\nB = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae\n\nQuotient = -2000\nRemainder = d\nA = 163956bc32325f28f48d41d32bb08d2a9c4ccbb0d818368fb13941e82b27da21d04094f7e897ce79c2d0ff8470505f1ef63fc00d\nB = -b1cab5e19192f947a46a0e995d846954e2665d86c0c1b47d89ca0f41593ed10e8204a7bf44be73ce1687fc238282f8f7b1fe\n\nQuotient = -4000\nRemainder = -e\nA = -3763f8e43bd05e6ffeec6d509bbe6ff9a9022ced8cb191c9abaf5fd0e0b75a53e2ad581455e3af09e702a77b164ed3fb54ae000e\nB = dd8fe390ef4179bffbb1b5426ef9bfe6a408b3b632c64726aebd7f4382dd694f8ab56051578ebc279c0a9dec593b4fed52b8\n\nQuotient = 8000\nRemainder = -f\nA = -531dd44dfa9e79a5aec8fa7c84bd3b753c146770d22d2c14a6d2125f7ab95e9b320e84c31cf3e0d883e1295a220f2a546550800f\nB = -a63ba89bf53cf34b5d91f4f9097a76ea7828cee1a45a58294da424bef572bd36641d098639e7c1b107c252b4441e54a8caa1\n\nQuotient = 10000\nRemainder = 10\nA = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c20010\nB = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c2\n\nQuotient = -20000\nRemainder = 11\nA = 179d7ede3db0c105525286551331d5b9e1f97a7883f0c13cf250afe9765bb5aaa527af7945c19cdd4596565cbc8532a3cfa5c0011\nB = -bcebf6f1ed86082a929432a8998eadcf0fcbd3c41f8609e792857f4bb2ddad55293d7bca2e0ce6ea2cb2b2e5e429951e7d2e\n\nQuotient = -40000\nRemainder = -12\nA = -293dc443c294c6a6c53dd49e84f58305d59a432afb6c7ea2039cd02a513231239571ae07f29b5427e869b9faa485511ca45980012\nB = a4f7110f0a531a9b14f7527a13d60c1756690cabedb1fa880e7340a944c8c48e55c6b81fca6d509fa1a6e7ea921544729166\n\nQuotient = 80000\nRemainder = -13\nA = -5b637eb8aa51ef15a18d9b144031c9756527fc0fb96c84b6df03700e5079ae1b3e96940a2c1e07f3b47ad8a9b2b8ca99171a00013\nB = -b6c6fd7154a3de2b431b3628806392eaca4ff81f72d9096dbe06e01ca0f35c367d2d2814583c0fe768f5b153657195322e34\n\nQuotient = 100000\nRemainder = 14\nA = 87c846f5469d4c5819aed0c7e77797209b2c", - "1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c19400014\nB = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c194\n\nQuotient = -200000\nRemainder = 15\nA = 11c2a4509f419aa977c3d37fa446fcf21b4b3b9f983fbaddeba4f51c285ac4032200711a54cc6edf24297b1f3d46ad020131a00015\nB = -8e152284fa0cd54bbe1e9bfd2237e790da59dcfcc1fdd6ef5d27a8e142d62019100388d2a66376f9214bd8f9ea356810098d\n\nQuotient = -400000\nRemainder = -16\nA = -39e37ae0edd92b957e84682358039f5e432c42492a44f3de01cdf74d643760260f2837946608663e12291e9b0695449c1153800016\nB = e78deb83b764ae55fa11a08d600e7d790cb10924a913cf780737dd3590dd80983ca0de51982198f848a47a6c1a551270454e\n\nQuotient = 800000\nRemainder = -17\nA = -72f725edd5a3dd6f20b5e9ca7da08a99f8ec9214c80588182c0d42e03bcff34b488b28c03cdf41813a6193c10672a8ee68f6000017\nB = -e5ee4bdbab47bade416bd394fb411533f1d92429900b1030581a85c0779fe6969116518079be830274c327820ce551dcd1ec\n\nQuotient = 1000000\nRemainder = 18\nA = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd000018\nB = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd\n\nQuotient = -2000000\nRemainder = 19\nA = 190790727c1514b4ef83a1c6aa07493c0af7087fbc8a675bfd9a1e97b8ef80ef684219d6c6f1a5fb5b919f105fd7717cdd5aa000019\nB = -c83c8393e0a8a5a77c1d0e35503a49e057b843fde4533adfecd0f4bdc77c077b4210ceb6378d2fdadc8cf882febb8be6ead5\n\nQuotient = -4000000\nRemainder = -1a\nA = -22d115ab02f8663d8c009960086a0275d301d358cd3b250bb9e7c16cc6ebed4a8fbe43bbced856d93be64a17377d95f5f9c8800001a\nB = 8b4456ac0be198f63002658021a809d74c074d6334ec942ee79f05b31bafb52a3ef90eef3b615b64ef99285cddf657d7e722\n\nQuotient = 8000000\nRemainder = -1b\nA = -41f2e708ba47494a13607223b08e6d99c0b4247436632961d873804e83446dc97139ffaef3e25969950bd4b5bb4ff73b1a25000001b\nB = -83e5ce11748e929426c0e447611cdb33816848e86cc652c3b0e7009d0688db92e273ff5de7c4b2d32a17a96b769fee76344a\n\nQuotient = 10000000\nRemainder = 1c\nA = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336000001c\nB = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336\n\nQuotient = -20000000\nRemainder = 1d\nA = 10888959278661bc36089519a215bda60f9ce24ff7c0ac1f543b6e652f94dbff1f32aa40cad2b4b4d676f16948551501c29f2000001d\nB = -84444ac93c330de1b044a8cd10aded307ce7127fbe0560faa1db73297ca6dff8f99552065695a5a6b3b78b4a42a8a80e14f9\n\nQuotient = -40000000\nRemainder = -1e\nA = -3ada453530a180fda58533ab8c62beb4f693a134f512e4d23e487dac3b575e5390c0a90992400e402bb47aac93d46ded55f54000001e\nB = eb6914d4c28603f69614ceae318afad3da4e84d3d44b9348f921f6b0ed5d794e4302a42649003900aed1eab24f51b7b557d5\n\nQuotient = 80000000\nRemainder = -1f\nA = -57879eb5d92d565daac3ac5173639bfe44b6ecc69ff770af57bd79c9b93841c5677042cb362b794f3d8b24b0d3b73ed1cba58000001f\nB = -af0f3d6bb25aacbb558758a2e6c737fc896dd98d3feee15eaf7af3937270838acee085966c56f29e7b164961a76e7da3974b\n\nQuotient = 100000000\nRemainder = 20\nA = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d00000020\nB = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d\n\nQuotient = -200000000\nRemainder = 21\nA = 1c267719338a4562e934bc57fabe6da86ca534a34244bd38c15032f01f47c2fd498c83f644b345c5c661ada0e586a096bb63000000021\nB = -e133b8c99c522b1749a5e2bfd5f36d436529a51a1225e9c60a819780fa3e17ea4c641fb2259a2e2e330d6d072c3504b5db18\n\nQuotient = -400000000\nRemainder = -22\nA = -250249f2185d4b428fa9534f03ef3cbed535bd31c56c0b273e6c3d35e0266f7777a6e59a99da5738b8e3af8ac60061d6716ac00000022\nB = 940927c861752d0a3ea54d3c0fbcf2fb54d6f4c715b02c9cf9b0f4d78099bdddde9b966a67695ce2e38ebe2b18018759c5ab\n\nQuotient = 800000000\nRemainder = -23\nA = -710b30c23c3c4e646ba90da33d2ce35af2ff181c40b02e3ffa607966730c6b6e274dd4c3c78e578e0b10f431f2d832274bf6800000023\nB = -e216618478789cc8d7521b467a59c6b5e5fe303881605c7ff4c0f2cce618d6dc4e9ba9878f1caf1c1621e863e5b0644e97ed\n\nQuotient = 1000000000\nRemainder = 24\nA = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719000000024\nB = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719\n\nQuotient = -2000000000\nRemainder = 25\nA = 1ed1b7d9e4cf3d44ee98ef69850e61a39f54cc407c6795c07c887374441fd9ec258c21193f8a8c55802fb8f8c579cf94cb0ce000000025\nB = -f68dbecf2679ea2774c77b4c28730d1cfaa66203e33cae03e4439ba220fecf612c6108c9fc5462ac017dc7c62bce7ca65867\n\nQuotient = -4000000000\nRemainder = -26\nA = -35d324ba37d2000f960ca1c9e1ab96e341a2ae6a5ea5cef014c73a39dde000d8ad9606b817ad67e4e4593cc5894d354854898000000026\nB = d74c92e8df48003e5832872786ae5b8d068ab9a97a973bc0531ce8e777800362b6581ae05eb59f939164f3162534d5215226\n\nQuotient = 8000000000\nRemainder = -27\nA = -7039477c3e0a6f415e25e9f9b1dab1edcd8a23f984e7e3bc149c206a3b756b1be001450af4049cd4535e4243d7032afcf6790000000027\nB = -e0728ef87c14de82bc4bd3f363b563db9b1447f309cfc778293840d476ead637c0028a15e80939a8a6bc8487ae0655f9ecf2\n\nQuotient = 10000000000\nRemainder = 28\nA = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba340000000028\nB = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba34\n\nQuotient = -20000000000\nRemainder = 29\nA = 14d27a16a9cf2fdbc85b88a604dd8f0e57b5b34a27089d75d805e05fbb367dfa61c085aa98b896e3e53b85ef774a3fa52417a0000000029\nB = -a693d0b54e797ede42dc453026ec7872bdad9a513844ebaec02f02fdd9b3efd30e042d54c5c4b71f29dc2f7bba51fd2920bd\n\nQuotient = -40000000000\nRemainder = -2a\nA = -3bd0119619fbb5b260c44050d61e6b1925a49713d754ceb06bafb1d730a93f199df654b153c40e75096ebbaf5a6ce3c801820000000002a\nB = ef40465867eed6c9831101435879ac6496925c4f5d533ac1aebec75cc2a4fc6677d952c54f1039d425baeebd69b38f200608\n\nQuotient = 80000000000\nRemainder = -2b\nA = -61a283fe41d965ee770704bb453f689cb82a81089422d6d904a91776a06d32857220286e6ef6327807b724062dda143b46890000000002b\nB = -c34507fc83b2cbdcee0e09768a7ed139705502112845adb209522eed40da650ae44050dcddec64f00f6e480c5bb428768d12\n\nQuotient = 100000000000\nRemainder = 2c\nA = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe10000000002c\nB = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe1\n\nQuotient = -200000000000\nRemainder = 2d\nA = 1eb7cfb197d19f56ad994eca52d1af6466fd09da07d68d63067602046b2d42d3063ef5eda6b58afd69fd92b0b727a0ecde1420000000002d\nB = -f5be7d8cbe8cfab56cca7652968d7b2337e84ed03eb46b1833b01023596a169831f7af6d35ac57eb4fec9585b93d0766f0a1\n\nQuotient = -400000000000\nRemainder = -2e\nA = -3ab858b3329e5bd0469118be52a867b2febbe2894d962cedeb3a5be1738db1cea106cd0710c9f6937348c2c63b109ae623d500000000002e\nB = eae162ccca796f411a4462f94aa19ecbfaef8a253658b3b7ace96f85ce36c73a841b341c4327da4dcd230b18ec426b988f54\n\nQuotient = 800000000000\nRemainder = -2f\nA = -6137bae6cf7573afcbb6fd5c066ba37648cba8db0ecafe9dbc66959b19deabf42f3083719a2268b7602bafa2140a1ee8ce7d80000000002f\nB = -c26f75cd9eeae75f976dfab80cd746ec919751b61d95fd3b78cd2b3633bd57e85e6106e33444d16ec0575f4428143dd19cfb\n\nQuotient = 1000000000000\nRemainder = 30\nA = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7000000000030\nB = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7\n\nQuotient = -2000000000000\nRemainder = 31\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -940693131e2ba7b2af531803794983337dd526f0d84d08d58723edf002a388d55c8502d88c2a2a6e78233a2a1b1c8d339a13\n\nQuotient = -611b743a0e2acb1043bb33de50a59eaa0405b37bf6b622075dd69291fe5b53305dbfcc377d1f3082319c153d0c1ffb3b3346\nRemainder = -16e346b6a4297\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 30c77f3380ccf\n\nQuotient = b9e34073d5e6e5b9e5d2d7250150f8ad86870faeb88d5aed5029fb25c176de216e2388e0f5d33f7c3b56102873eb40b06f2\nRemainder = -16ebc86eb88339\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a67", - "3426000000000031\nB = -197b6f6ad5b75c\n\nQuotient = 141bc8752e846cd63743e6fce4a22efc3eb5f0ce46ba81b8f578c94c516288ec3610fc9923f45d4af2b94c0b0a20b48ed0a\nRemainder = 9bab19f12d81c3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = eb90162ecae18b\n\nQuotient = -381bd85c951e1dd775b0d7fab344aadf06b1b592c643b5852fa44aa55159eedf3b3e47fe0d9f399ad92da85ab2bfd18240\nRemainder = 1e4f817a2f52b71\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -546c109fa8a9d7b\n\nQuotient = -5e385a83b56830626cf8306acc232f955178080e86384bbcf92eec3a8961360223c4cfc1d8d118022972e61866cbfc46b\nRemainder = -292e149300fdd1ad\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3246242094394c8c\n\nQuotient = 9af0246f4b49316df43f61ae3795a764fe9b1d071ce227982ebda7988a7a7a98129c94a76635c6913cb15e4f75ea1608\nRemainder = -dd3b3e32ddc79cb9\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1e928618913898b2f\n\nQuotient = 1fe40099811c648aa4e84e4fbb8cbc19706774a11391fc03a9667d8dc72dd0b26c4a46d0bae56ba90fe4bfac1517d241\nRemainder = 16e021603d30dde2\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 948887c1634f4b08f\n\nQuotient = -3f4fa4c179dab02ad461bbea8f890292c934496db560f72878323a4463d77ae261363f4dc8f53eab145fcc3815d3253\nRemainder = 407ccb4f0b814dc5c5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4ad17434071e1ce664\n\nQuotient = -4d17d19f7f6861189a520776339a1e425876808111c303e391118714370111151ef4ad2e6e84250f59b0fe09ab3293\nRemainder = -36f745b0f421d16db7\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3d71635bcc25183cdde\n\nQuotient = b976d544af44e711351c6618106d3a002c42ebbe22fe939a2457d24e8dcc35c95dde5c7c77af6b4545344a198be82\nRemainder = -107334ab98e5099fec5f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -198a54e35fa0cfa328a9\n\nQuotient = 1307bb8e89aaff7466bc238d32672fbbde7be19d15423bcfa14f9a23fe85af9739b72807fd4bc420ad0b0fac37a42\nRemainder = 170ebe9b83d4c43b79ab\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = f8e923a8bbc0242eafe3\n\nQuotient = -3925a167c1c4d2fae265f277302b989466e309a7211e0b7173031cbbb91ab7fac8dfe43c9d832764e222e9d8581d\nRemainder = 4d404e93edb435dbd60af\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -52e36cee22274556059ea\n\nQuotient = -4d5a6ef346a872142b999ff9a5429198b3c2a97e968f55aa2c01583efe30e9687c57e2bca2372db4d3d443052b6\nRemainder = -3a2ea5f9d204dc31f21833\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3d3c79a115d9071b573d2d\n\nQuotient = a49dee54430f1737a04543d5f549efafab25f0f28f5e304f1bbca191f99521c2c4be1b9927bde19e1ec2060bb2\nRemainder = -17d02758f8fcadca911a95f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1cc65a75211f2826c9d0811\n\nQuotient = 1808ab7c0ccac2ff8f7cb61248bf4624fb60352a356fdd1408904f8c6fb0cc52b7642ec59183bcaf5dd89ca0ac\nRemainder = 5c95323f3b8861261dc31ed\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = c516e6e3fa6e3dc52cf5933\n\nQuotient = -437e04d7076794850aada0cb4ca7a1055df103e74e00766be6a2fdb2631bf294cdbf2695d0a2f8f9eb5587aa5\nRemainder = 1fc63797594c56160536faa9\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -462ee529b488d1db2b6c60e8\n\nQuotient = -5dde5497accc4575a412e7232ce75bdf7905936e09e382d5c9f133faf82a05ad9dcc94ad858aed34cc14c714\nRemainder = -15e79293d5e055f906381a899\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 32765b0a34c88864d39bedaae\n\nQuotient = 11ac52a9287472e1d3b8577b3d50c95076e190714796761322b3ce869d96b44387e190e824849ee345d0a22b\nRemainder = -a158ccc7c055d64e7df3fbcf0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -10c061a37f6cbd11bf0c327643\n\nQuotient = 1ff5cda1551867577c5ca72c86516a82fb8fc5f59ce967b73c6bcc1b85168389872c9a747ddf044d6dba174\nRemainder = 21e766a0020ba429b330a325d5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 9435cd2dc2a92c950bb9e69b83\n\nQuotient = -2719c892fa3f4dbc9951b2095056a16159adaf32dff902e20a800a0cc2e858ccae408f2161aae25d3e1f6d\nRemainder = cafbe9caa1f83fd0dd3d5a6881\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7924e4dcf8f96da61f54bf83870\n\nQuotient = -5080dc99dba295f4a2d9a474c2ddfa3b232a82fe629fe62177514988983eff8195b37d3fee3afa343b497\nRemainder = -94ae72f78982ac1ff83f300cfe8\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3ad70d4b6b9b5f5b2eb65da67e1f\n\nQuotient = e475eebcfc53d49ffad2e0c2a4ba48fe7ce02c42ff107e01ab3fe5b26eee45c83c4f58c181d77c259155\nRemainder = -c83ac7582a02b47ee734e0f24dc5\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -14bbcff5423a260b21895327b18bc\n\nQuotient = 201308a421b85291d23465d648ad2a8d6f3393efc16fb675a42ea7bbca635ddd8c2449b1b34e5db30a03\nRemainder = 8e07efb8ae4c9df39533042362081\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 93aebb72a81ba68e8881fd1a56a90\n\nQuotient = -2584cc534f88f091fe471c652ac66a695906a7cde1fc1cde9be3ee09026b690c1a899378ff31f6acb90\nRemainder = 794801d9d5770a60e312b99d6b9f91\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7e408caf387a0ce9bbf4309c80755a\n\nQuotient = -63f7bfc0fe5a5421bc0a19fa6c87713a72eeb2a33e5eadee8c2f32c20d14f403ab8bdc424b9e8e0c68\nRemainder = -24227c242afedee2473c1a66a5cc29\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2f622c665af7f8126eabfd90df8e9c5\n\nQuotient = e557e6d2180aeeee5d2cef453fbdf38e84cc148f4608ade8836045498be2d318520ffadcea6319432\nRemainder = -dd290149e0e159f9ba6bb9f5a4b003d\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -14a7623d1d9dfc177e913d3119d0d30a\n\nQuotient = 1651d852316d472b41ba0460566e43fabb9257861859ad0fb6ea5a6433a4164299e078f4d50c58afb\nRemainder = fb60aff5fdd2a2b794b0d973ac4d92a\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d439da27b5e70342aa5cb365ece15665\n\nQuotient = -3ae357761a8ff43d3b1bc53eb336260342a39d22f8fac44eeeac96c2f6de32580dd6a688faa9c515\nRemainder = 4fa6f7ee4faf2f6be99c5ce4b65cd642f\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -50700f9c0da59482165a47a3eda2bf07a\n\nQuotient = -543b4390e4e254226683aa0b83b2ca176ec27a373969fb88f766ac72adc9125ff83b2652e46afd3\nRemainder = -12ff398d9a7d9e97a7f63a0bb293c8fb0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 383c5a4f1767e83fc382ad4f1c7c2b7ddb\n\nQuotient = ecb72c14c59d49287fb6b2cacdf04619ee617d5f3f0f1b2890fd4e79746a4fbd848613cf5eb437\nRemainder = -1035512a2717a89062d48f1bfd213333ed0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1402b751a1e5f3fc46e22b43240d6ce9b27\n\nQuotient = 1e800ddc5d5126f322298383f32fd593623eb88a91b2d68c5d9f56e20c16ffe2cefabe87357", - "0ab\nRemainder = 72935d534bed5ba557b91ea023601f50b1d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 9b4df766c608ff3efe5ea1f65cc850fa73c\n\nQuotient = -2c2dc2378abceb983904cdf6728f361d279b4c821710ae785724a7251c43fe4f705f023afa7e2\nRemainder = 249f6433af4e8e224eb570fd438197af62f3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -6b382f812816c77d65c94c0c660b31a69b8f\n\nQuotient = -5f3ced1e42fbd3c6b2c6f1e16953e0c1bb6efb4e49566f974a968f69a1a66a3d7558f5a802a8\nRemainder = -317a7fb1af65982fe4641fbb1e5837e6ea3e1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 31bc97372d17038fd842b72eaba2abb26df62\n\nQuotient = af3fef8111c449b9e0858e7e53e1d00b764232f7a077d75043249c387ece30af351c8a40335\nRemainder = -a1493bcbf57a8480461d62796aa8f8541ece4\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1b076b2f7b78b4a0f0e24ba3a05d6c697efab9\n\nQuotient = 196734cefb08f09cb32ffefc07da8d9545d3451d5a08736757184bad94c73be71311cf1e01c\nRemainder = 273e33521f4d74840a96b3fffe169f79d32855\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = ba7746f4400f812919a3dc86b00642e1487691\n\nQuotient = -3c5989cf33145057a9c8e904435d12939db519cc6b9ca1c0a11934399cb139a73613950f2f\nRemainder = 456ebf56c636d54e37709b9e799e83b7a08cb93\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4e7d4f389423f42e980eda55b4a6a45f6f4bdc2\n\nQuotient = -8432cf3338bce1d12586f83025aea50cff3864af3eb2103a36bbb0aba10b0ba4831641633\nRemainder = -4f62c678137df301c4bef216e6aa910104e76ff\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 23d4c57b5a8162aae8d937be12efbcfd7b96ec06\n\nQuotient = 9f94c4399eef16dfc65a1e015e0786c86470299865932c4d564b71c9b1551a9c0308af38\nRemainder = -168b74a6073b4a5b54fa14aacb5c3bb7897ed0fe1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1daecf01ec633610373b79e04c22cd7499012bc66\n\nQuotient = 1d5b838dce6c0324f157ad125adefde6e1045dce9ff97cf8d1d39b79bce02128e3433ffe\nRemainder = 3aa816216d55fc3c910a030fd10fbda1e12f2ac2d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = a1598a12a84e9cba42ea0e200e88d4599c9f615fe\n\nQuotient = -3edb182b53890ca8762f3039d2d71a8a27c36cc884d0879e0635e6326af0182bc47cad7\nRemainder = 4610b2b1305220bc0de584dd3f87d90109012a8077\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4b5c2f1ba3a82047c9de61d47cbf1bec86b6ef90d6\n\nQuotient = -7571ed4c509630886483f6ca0923859e644063acb38cfb338bf3a681fe449501262516\nRemainder = -21c579846594fc3e5efc53ab01576a7b32d69faf41f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 28550e1f7c6492f4cb682c37b105f92b049c13fc03b\n\nQuotient = 9ed8fb31327a110ef4377258681c5287de8ef9dbe62aa4fe84a7f2a94bb69607cbdb2\nRemainder = -1b7bb759dd0ebc346cbe216e56be8063f063490c17c5\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1dd1e61caed1efc07d21ce05d889de1ad65808cae026\n\nQuotient = 1aa716227d1ca6af68286062b2d6dafd7ade16abbd5d6fa4ada0365832fe18f73bf35\nRemainder = 32e714b0c4ecefb38735cb88cd5e07c21c81be858cae\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b1b959a7b3262d7f4dff488315903aeaffd982b726d7\n\nQuotient = -2a9979a530046939e0b43a25edfbea6775784eb5cf346a9fc3a2d22e1aad473cdada\nRemainder = 4edeb91a2472e80068b1883cf2cc45d68ff9bbed1756b\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -6f31bbe097587a68fdf01d0bf93830bd03a23920ccc0f\n\nQuotient = -566ff76814e1c7d31ad53bfb9f3c0607ef1f7d1cf9bdee6e1cfb78b3ad7018f8bbd\nRemainder = -1eac095d6d84021c33aa9b219d191bd0637f20b5920eed\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 36ccf5bdece624b4f54c729a8cde13325d8dd764f44894\n\nQuotient = aee4f377611179d8b6315811dd94639aaaee63e99bddcfa8eee297ce1dc04daf8e\nRemainder = -59cb3ba7efa1637c46b21795872e8deaff90f13402cfaf\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1b157ad838684b45065aa77ca3238a4d8c5427f719cdfb7\n\nQuotient = 1c72d32cb83cf4a9043d3bb5002f61b03e29c34e44a9fc5cc4d613726f5e618546\nRemainder = 7312d11fb5828c7f1a0060a5152a7644fc1e6a59de28d03\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = a681444c4d47d829f7b629b561ffaa0c3be1232346c907d\n\nQuotient = -2702afc4095a0396215e3ca36e2a59725f743b30de0dd8d4ec4d943fef6c37162\nRemainder = 223dd3080ede3a64744b14df8742cedd71388b0df99073bd\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -796c9ea38ccf516a2054a1e584c18b64b996c9679960585a\n\nQuotient = -805585c6a7badc933bced6f8373ffdfe9796e963d3fc90e85b1a22c38f842062\nRemainder = -a6ebff3f651644915d5c466cc2915d104f0f85a44e08fd6f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 24e8fb7a6a3057ddcafff92916c46f7e4038b98c3104ae831\n\nQuotient = 10383ff8feeb180d4fde925b534be97ec3d5f1f1dab5d8cd9ab5d8ea646cfcdf\nRemainder = -a7efdd0401c74a69cf74442fe3da907acf92e8edc51668828\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1240a71ed8d81e86fd9b16e1d64f438b35d6f8eff672494017\n\nQuotient = 195d95a520fd22317492117dc756ff97806c48c1aac67a41ae56fe503a60cec\nRemainder = 8b8692bee56f8a1ada9ffd8b3583eae33a0df9b73a7d8585f1\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = babe02063b61cb90634ac0493174073d2419e00728d46ad2b0\n\nQuotient = -37791adae674b866e4791c107a697363847dee4a58a37806391426ea48b8c9\nRemainder = 33986fc6a5f5c4f4e31458fc7de55e08a4e9320509d90299b93\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -5563bb852e7338c65aa21c516eecf47f498e5788c608ed46cae\n\nQuotient = -68a30494eceff55e4f54a556dd9b30025ccfa22c0952fd746adfd13d31d00\nRemainder = -1b511d0ab81d528d00a1058850bef48df2e9ae9357e779bb9231\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2d44e919fd27bb3fd2093062d11830c30fa77febafe0a2082cc6\n\nQuotient = bd30999592dbeabb8871b76aa04cc1c6c3794a83f0178c2ad505d8189485\nRemainder = -b0dbce286df5faccf0bdb40ca60f508d436f9410c5e49c3f1360\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1909930e2d16fc877c15895a3ec8b2125858bfa1c5a1b8776bedd\n\nQuotient = 2171694ef4a9d57b83b09357a511d4e11cecbab5e9387928b480d686a0e9\nRemainder = 29abc8898d5ef85f87323c2a6fa36ab6e1bdbcc0ca742b1a2347e\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 8da37bc9c7c9bdc62f49cadcd40e156e776b7f4c8f7ad543f463b\n\nQuotient = -267d470f32911150d9944e684c14e1834734b15475bee968748dd5f6502\nRemainder = 53a2ffef61709bd7143c4c876e021f20a99ba481f2b11abcd45da3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7b117ddccee97816c2ca2f1a612cc0d94ac67f5a79ed41744c8fc7\n\nQuotient = -5a21a3bdd3a3d4f1361a978706ba1cec409c296a5b3c369e91fc8317bb\nRemainder = -2cdc818f1e445fb3772d2a56833aefb2f5565a5fca80662e6fc1845\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031", - "\nB = 348dfba3c793f0018d7d3a70c4060c3148b4a3163ba60af9d6f8b04\n\nQuotient = b301b4050fdf4ede8f9c746b26d968110e1eb119ca42cd9c9bd8d4fab\nRemainder = -17993daf81711fe59204ec82e363d2b91971129af9206ff9506d3cb1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1a76328184b9bea8770c91cfccf8ab98e75b2224d666af58022aca80\n\nQuotient = 19c401336dd43c221a61264f8b91791d250e6c99c61850efe6d1e3532\nRemainder = 6c9e547a77c98eaba1b021777dbd98ea88f7fd37c95a2b182f2b9067\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b7d7b1f95f4fe2f267af88b81af88fbdf603e54ab6de73ccd000c32d\n\nQuotient = -38a77853de88a8db14612884b515e3cd7c673175779d4ab71ba58f83\nRemainder = 51851549cfa00dbfae388cc3b46fd4824268e00e12fba288acceab339\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -539c0171f48e4160e5c308ee9e74f35d8b6d032e946dbcf748b1335a8\n\nQuotient = -79a7eab82e5b65f4f6734e8803fa7c30852ea3ae56e801c5dd11778\nRemainder = -f89592eedcbcc68d5df80663b3cdc638d9d779707d4ae5a552d97d009\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 26efac15401a945ffd37066bc5af23191292765164a0f1e4fd537fd64b\n\nQuotient = d33afb58753a21581c5b2351a74f3d220599ed56ebeacf1d43eeb2\nRemainder = -f699437f44af44b3ddc080f5b74f753d35f70baf3866040ba3c64b30f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -166cc6a3c60facfa0d8d318f26c6514c7eb9113f6b625c1de804ad379f9\n\nQuotient = 19e55bdaaa5a375c36e6869700f8677db563e5cf985be2a8d1b012\nRemainder = 7bccc3a653f29f3f45b52b8de2449c868c64d976666c01bff2dca03a8d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b6eae7a82b5dd1554795573cbf558d7cfed813eec270c326bf290adccc2\n\nQuotient = -297530094c3e4270ab5cf67e60fa5af6a32eb41b18b050fa6d46d\nRemainder = 62d8b502e172da7bce53fbb7c1ae376b6c21b3a3a47523aa0023406e353d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7241ae5f1aaee9340d437ad2dab94b70dd29fc6fff7fe31b100aa5001644\n\nQuotient = -640f3c38230962c6d6fca459afe0e46137525e8d62dd9b84da73\nRemainder = -16fcadd5155910764ecf0b4bd0afc3707e2ce49cedcbd5414f1c7d860e95c\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2f570d2da7a4e62097eb494ca43f7bde33e36525308dc864ffbaeb5d48f97\n\nQuotient = b3895ebba13c8f383ac0482be02e1f5518511420cb4513426bb\nRemainder = -21bc847fdfd48c7a4c36c778681ea20481081cbb7af6b281c8b8ebf2b2c3b\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1a6233954b3480af5f911a6bb8ad33967d5e0446c3e56f521e892c986b6b82\n\nQuotient = 243f3fbefbf842c79c5e96162fc42fe4f177a59d27681c54b3a\nRemainder = bbfaf15a90e744dc4a1caceda3cb339e5491e4507a1118613c5e9739f976b\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 82ae783b8a13e2e65d52dd3a6d6b057163347872f4d72245ff364dbf2421ff\n\nQuotient = -30f7cef2948c9ebed8fa3c5ea9a9bfa96ee4e9729c9b18e9d3\nRemainder = 1feb3fd887629cca60c664e385dddf538d9bf7fff2d34ca9e0e7614946d807f\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -60bba60d69093c0134fcb90aefdb9c190e7bf037ecc13dab3cc7915d7893046\n\nQuotient = -6b6f0183c1f598a68683ba7435c05d700d74681fe472669a1\nRemainder = -1f4d58f81a8c18523918d31791a00ea9aafbbb87792d90a5392273ec4e405da2\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2c17372a5128d7c403a3b94838072ecf9aff88d164764b12bfbf6261df957e2f\n\nQuotient = c4347fe42b2a7d9d5a650b72724369c5c1f59262a7be3fc2\nRemainder = -1103ec9c4a15373949cae4e34b7b42e242da41edbf5ad8362ce5e5426d3154a1b\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1824671758069b7660bad819f06c86fc76a9344ea38412058380363e5c5b4086b\n\nQuotient = 15e8c8d6847dfe974cefeef5fee93da9e58b74d640c6c413\nRemainder = 61dac240f2b39832903d5ecad9cfda5162bf8ebb0610545f259b75c3dc6ab8771\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d83386fb9682576cc70cf84520c53169e391b414f5421cddca6e257bd77753c40\n\nQuotient = -3572711bf994e6ad48535cc4d65ac323ef1ccff530b4337\nRemainder = b5899d4cb879e37022c539962959339d055900cca16153da09b54c658753cf50e\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -58a05faf5c61f85ac5a090b6bb045c851ea17332d9bfad4309ce2b7a79ad3cc575\n\nQuotient = -6931ebfc6e34305e5d7cba5284829d088d1ec0abdde508\nRemainder = -1b09eafde481064bab3a5c7fd895edceca40b1e62a9cf953eae1061dfbe00936391\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2d0769f392ca9ec629ef1bfbdf08cd8cc9219330ffe3c05343df792dd94b1147714\n\nQuotient = 9a4800f0cb2bfbe8d234410deb510103b7da30cbac7d9\nRemainder = -971e4a529e439a1b96b942001631027ff2fbe40b8939e224adb7f2ed30faff64d1c\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1eb3d7971125a036c3a67d9f5ce580a4ef4c469a492be53a55bafd2eafd4032b5b9d\n\nQuotient = 23116704b7a1a86cfa2ee5707ee46268634db5d50dc0f\nRemainder = 467c6b64c8121e4f250492191ea36a27119a0a6d19af519bf7ccdc2436c885c99d85\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 87134e98f73470e23a96c6a9139af3d4d21574de8aa9ea1d720df8940bcbda343694\n\nQuotient = -3b7f72ecf4f55c02366c52f38a827f5773b7cdebb9ba\nRemainder = 194b334b2046a66be3ddd7c6df01c88967fcb11e97b8206d000bcf6043c6e9ccb13f5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4f9d0341cadfb1f0bc38184d93503faa196fb8170f8ba2b5d3b512c09d39b7f79a5b6\n\nQuotient = -6db1d69019dd4cb26fd65d5b88a31bb6413b30278a1\nRemainder = -2042a060391e181882dc0c8d91c3b03c1ea35e2eff01babb3ae876ba1e57a505d44856\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2b2e8f445c0c3aaef0285945e4ca37a700310e003086f34d02c891b94b117f3d3032fb\n\nQuotient = c0e5b9a5853bb21b5e2e37f469764579d5cb2bf984\nRemainder = -154669d4bce7914cdc8d79f2b8d1faa43e8cc3b20fb0767e1c9a47c9e1daed4b665cfdd\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -188e619dbb719381e701363de874fe168529c10f30d3ff184e4356991fdec1649f72235\n\nQuotient = 180054f8c36833d44cab9dd61e6d89d28605c564af\nRemainder = 59192ec5c6fbd9773b8b7dd7d8ab1800dfecc8eb01c29997d15ad75b79575d9e26e1fc9\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = c55b5eb165c63ac2794bfac21980ebacadb93f1e059309fd2b855621572e8d9b3f29018\n\nQuotient = -31412e97045c19ec38951b0e3884c66d1d7479437\nRemainder = 56f1425227bfc6eb1ecda7bfae0e5cb59e92a2cc5306b28465c8739e40893dc5c1e94cbc\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -602b8c25ded1ab3877f58cb048c733649c7dcadf87b2652e35c4e5544d2306107ebff7b3\n\nQuotient = -8da1489ccf7203ecead94c67a5750884122b6e75\nRemainder = -15162026586a1e55dda72785f31c9e6140d166a1fd34c87a7d8c78f8d8f87bbdcf8f75b1e\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2171ee4a6f7f67d5a33d0a08c367184d70ffe39da28562655e75f6b66c866b1c2ac93e467\n\nQuotient = e635f8bdbf80e99723aa5718d3fade4e573be2c\nRemainder = -ffbd73bfe05f95bc2b135f12682288c620215eac3d6d56503d93a90e06f236e597d1df975\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB =", - " -149375d478a096e724b84faf795c589ef0d772c4623f5be38da99006cd833dc5b28363faed\n\nQuotient = 20f76f5c6d0c8284764a10f6936c22bfba5f851\nRemainder = 82e3fb3f7252dd87b5370d26d9e8b9e98c7d333701f0ce8a05c337054c7aeb343d04d7e342\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 8faf8c0a3ef94ab1069394998e5412a7d84f44aff97edf63abc46d96f897172c38faa0b13f\n\nQuotient = -382586dfe93872abbe3a504fc62a8973913f96\nRemainder = 4d407323ef56093eea2f3993334215950f4e1a85ba18cdcd77d819d92b8b292c3ec8edea425\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -545d81ed25602b158bc79aadf98a8f655fc399fb8652ae94333bf54c8c9ffaf8c6b3f2a9d52\n\nQuotient = -7d179efc493eaceaf46572a1f3a62bdfc4a38\nRemainder = -3de3d817a9cf7d529b5229a503e8ebbbd2c53215ac3c584c010947f780198dee16ffbf47791\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 25dddb00f65d6a1ba8caf7815a8063c5da656d775eae9e0108c68ce11dc925183810888dd04c\n\nQuotient = a9f7e5f235bae0e3e29393ac5c99d510b009\nRemainder = -150478b4a0df3eb20dcd1be8da283a00636c021c5c6337e7732aae9c4b49853b95f6d2475ea7\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1bde6cae7f5ced9006c0b1a61fb50982a433e4e2050aa486298f456556d8e909e96933e2ba3ba\n\nQuotient = 16de125df5936181981b4c2d0051a8b4d211\nRemainder = 29ac7c8a11f9beb9ad649257994216146b663bf4f237c561bf315d95778fcdb1010283475ebf1\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = cf24735a60ff5906410be5c4d98e3c9247919b57e404aeabc7eaefbf07bd64762bc61b96c9040\n\nQuotient = -268a52cd10ab4814268f66d9f44f71a98eb\nRemainder = 20293699f12fbfef2e391963866fc082a7884cd13b1c9bd8d5d203558feed2b889720be936451a\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7ae7d548212830013b7d653072c33f0dd54a6ebd8792bf75809d29a8c798dbc67c3edd99a69b85\n\nQuotient = -8f051067ccb82b6a3dffedd0ff2ee97c46\nRemainder = -100dac0d3bf5aacc5fade281c071eb2399560a65349566567ce1c0c34e43f175a575ed1eeeb3b07\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 211ebb5dc59a051fdfa3b18ac491971e863f2086cdc099672c1215af4ec877e29950efa4f487be7\n\nQuotient = 9b7ee4c499386f922432fcb1a453ee2ec\nRemainder = -f410122a74386d724cdd45b2e548645ac5ee4a44cbfecb82aad34ae470526674da44ebbf557bb75\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1e76750814dec1ecbb1af0fa2281ab3185e94e47fc16a77fed312f23f261ad7709ad7c9f85862c1d\n\nQuotient = 23efb26228d7bcf281cd45f54572e2b3a\nRemainder = 65bf2ef1c2f8e94d98060aa305f85e6cb869c74eabad99877010d30654aa2e578ef6aa3c5f1122e3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 83cfc25e90a61cf8686e3d5857b2f958674d478622c54cf8427275ca5e9312ed24e44ed4a1b5e413\n\nQuotient = -2cfcae0e922f2d884bfa0a3346dc9812\nRemainder = 14de2725b11a9c6784d9608c52770d29b9fbf824ecd4890bf28f3ec0dc6c52e4df9be540332b8882d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -694b057ff381badb37c7c15c81e74cbd6774e8d61c9e7d450811c36262ea834fc1287fa59708ee072\n\nQuotient = -4c0238ff3c18d4d58e543f020002802\nRemainder = -2ddef796c50817e82ea6f64a02a8c6b30ab40070ff5401c2d39ca14b9c4d99de33834bfe566a0c2efb\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3e51c9ab14f522b55e8f9d3ba995c0846a864dfa2d568ea211b0cac1463ce6a1da72d0a15746fdcc9b\n\nQuotient = d41f9102a7785ce64f76b7d7b870b0\nRemainder = -106eaafdd518c658bd371164ee43ccd915a01b513fc7d220900039ff840ba36450e16ce9987e08e7141\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -16549c5d57b531528dd4d781f03cf275b66cb94eba038b782b739c3ab30b8631c8706abac06004a942d\n\nQuotient = 1616b432b3277e774aad92b0cf544c\nRemainder = 2c89373720b834d718ff3df985ae47c3a7cde0e0309f682f5fd48dc97a1ff3d69fa0dcaa1245e956445\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d6721300e877a8145d05f4f3d8085697c2ca5f34a5357fed0bdb7169f83b6f8d855232eeea594846b79\n\nQuotient = -320fd6a7375a42a3961362ae196d1\nRemainder = 5336711bf81237ea3449f4e9f4e6358dc250f8ebd86082cab92a8079f2c8f835bc783082efb0ed7e3f66\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -5e9e8e1d446fdd314d487cac1226088696e33161d923acb67d3c75e87e428bdbc193e02f53200610fcdb\n\nQuotient = -4bd06daed3f30345d269f51e4381\nRemainder = -1f3513bdefa40662f0f50a04b418a833aa2f85522dc6c399298b1b147662ef2164ddbfb7247ba9511b8ec\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3e7ab7ffe5f63a6c1e109b95b83af470ff820cdedbb3c90c398ec42e44a45e1ca894870a7fa51f17ad5c5\n\nQuotient = d6fd01a0c5b55fbe36e58bbe77b\nRemainder = -c51af3e8b430870388357cb366ea888bd7b4ccde09ad3a1d2ee1426af060245c6d6b5980ae87fb66c4642\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -16086df3dd5e665f2631a294563c68931faa19ee67d6a2153d262940a648ae71bb3c1745daca5ea977331d\n\nQuotient = 18bd9a8f5678d28cefd955cf99d\nRemainder = e193f2fece67b7abe16373c3f84f18dfedcf654d951bf47585fccfaf67ee04f5037354d057c9f5eaa8eef\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = bf758acacd11f3f3e6665cd740517c9ab2384266f3c7ff9afd0888cdad2f6c9401c24d6c11fc3949aabbaa\n\nQuotient = -371239db55c79521206c9e60c0\nRemainder = 93773085af7582dd298b09d7098835787978d820289ea6850f27d0d77eecce8614785e32b228f46ca4b371\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -56033fd85be464301f10177b58d895fbb6df6154da5c2a2a7cfc3a24d83a96f5295fb17a08148a4e51dde91\n\nQuotient = 696d8e378d12221e2d970c53bf63a20ef381db8566701972c22fe067cdba99c57b68706a5c6e52f21bb3de861e49ed2141b3036f07d1fd0ee\nRemainder = 9f0e50ca76031b\nA = b2668f5fbcf4170820ed3fc9b12a61862acf8e3cb17175482efe23c5cfd3556e77634d407b6d1f98a73437a8d6066319a7a860afcab2338a1b1313037e30f4d9\nB = 1b1313037e30f4d9\n\nQuotient = babe271ea266bc7bc16d193097903037819f82366c7e9ff8f2cb14157b40433c6ee327038d5dcc44140b070d823befaefbee5e13419f6f17\nRemainder = 93d7c547a9ba0a4a\nA = 74b1a591f449377836f378e05d2902b29964df59c6926e5a9182cc09ce3111783cb7021a185340b4880d56635de268d6f3855c4d9997373b9ff8df899ee3b3f1\nB = 9ff8df899ee3b3f1\n\nQuotient = 890139fef28aa3b77814e1122b9c7f26e746ee3c507e6082b508fcbe380de83b06a01f735239c6847c30eae44749fc8c5e3bd97eb40ba297\nRemainder = 6c97aace900389d0\nA = 7e89adea82b4cb6feb41297b6dc8d948e72c3d5554a987900e7fae48cfb38fb5282b13d9a1f5793cf7cbf1ef551865041c3ffe0e287714a6ec7123556af55a48\nB = ec7123556af55a48\n\nQuotient = 1fdeead441e2d7a6ce3cce2389b2a22248ddca7970ae3f7e7d8453052fd08534ff7c46f6a4537fb6f28df6c5fc8a7d384336e679b74205315\nRemainder = 2903c7cc2651bfa8\nA = 9ca66de3d83f0a747fe986464522bde5e42aeac20e8ace1ea13fa6bc9514c58517479a4281d4128c6d775489b85dfd114ad184613f308f6c4ea484a22ab0ad1e\nB = 4ea484a22ab0ad1e\n\nQuotient = 12f16c8f9f898a08853982e2ac5a906d784c5ab8d74007ba3ab311e861d7c1ac115efe694cab7583f75a4a59ceff2887dab53b2f1022aa452\nRemainder = 4bdaf1f352e87aa5\nA = 6e6a97b358b591b78db43772378dc084a11836ddc9dd4607f263ce620714e8fdf6bf67387c163b6f2999f84270802b4bd5c0f0377e949fbd5d42fe145e66ffeb\nB = 5d42fe145e66ffeb\n\nQuotient = 14e0c06c8cff1f9f5dd8afb6fa6c340f0953a18ba7d2b26b22d8e7f946ef20fd5ac277ceb59cbd4ce3e8213803c3b5b0452ed449e22bf2c29\nRemainder = 55422f1caf4a9a00\nA = bc9c054ff568af73e301e0751bc1ee055e82826cdc53449f2d9f45feda2ba227bedd6df9b74fb58a85917d60b087bef04a156a571716e9bc908ae83784ee35c0\nB = 908ae83784ee35c0\n\nQuotient = a457ea94da3237c0dd15ee30e9c13e7b4ca1dc90fcd67951b8737872", - "06babaed837a3eb17e298d74cae92d1059636f9aefe11aef9ffa31053\nRemainder = 124768541b600598\nA = ea6dc82b1906c277526ed867fe8b0fbe32feecfb935dbab860aef59a7d72799fd4e952e70b4c9304c7b2a06af8badcd6cfa12d0b6c9db38d16d2c4a24099ca14\nB = 16d2c4a24099ca14\n\nQuotient = da0a37eece8972a0e2e8817c54e67c4d9f92373340488539d5051984bce0ae3300ef6ca9d0902daa4d485dec3b4db6c8b1ffd2c5d08b18ae\nRemainder = 1ba15c46023500b9\nA = 36ca8763e20e6ebf07a55cdfdd83892bef0bab68ac092093bfdac1a49c1da015541196a24249bb2262e70f7ed53e0fbae61f02ebac4b61f740548136ce50f243\nB = 40548136ce50f243\n\nQuotient = 3d8c433daedfbf681b528f88d610204d33bbe74d0b13978c34a617ae94177e07a757519b5a8f1a93a73d0751c7b5b72b4bdf475a9708fecac\nRemainder = 4cdfd72349c6110\nA = e0dd7e73b2a64dc017da65992176e2535c43b6fc14f2f7b0a7d894d768bbc77507eac0112b2dc3ca83d70989a1b949ccf374be6a012d80a23a74bba39671fcd0\nB = 3a74bba39671fcd0\n\nQuotient = 39d084b444e39c32f2883e9968301151802da15141f65893f37b8b834eb01c074aa1e1a978c5c99732c87ae106bf8db09e1728c8bf2aae88\nRemainder = 2950443357cd7477\nA = 16df31dc290559c3b6a3d192cf15d825cfe79f8dbd5c9848eac7fa90eea5d87f8b430cccf9baab3e8e4dc33467a4234d8551ff25e33af175654686ff1368e96f\nB = 654686ff1368e96f\n\nQuotient = bbead8f70c8e61114f22d36e97861f16037efabe1347613e78c51d7f539065421a66c907faddaed13ad2a0f0b00f8fd594e917799cd937e5\nRemainder = 3013136f5f728b68\nA = ba5e688ab4f8ab5c25592bc4334b6dc2b7a06d491d0f919b716bf1cf109b62a30d9dd59dd4bdf870dd2687894edab303277a5f3e3a537cc8fde3ee3bb61767d6\nB = fde3ee3bb61767d6\n\nQuotient = 42aefe467ff2a5614efef1edce25a1acba9c476b3abbcd680140a3aecf8f51c1ebaab8912de217451bfaca2842c0bae717b8a030b6318c0\nRemainder = 1f130dd2ead0d35e\nA = 17bd50b5322c51ac883852ad2a4446c039dbc210ca3aa0313065fc88cce6819b324e93b036bd0c71be58586cd2b243d01a4a918c10ea0cc5b22f9d795df09de\nB = 5b22f9d795df09de\n\nQuotient = 13de73dcd72a3638fe2a907fd7f6574bbb228698fa60e4ecffb082911c5f09c74bb4f50564d3d4035d07eedea38b634a3e3acc26c8e9aeff8\nRemainder = acb8702f0113e0c4\nA = e0327b2e59236a3f91ccf960490cc69b2afc854de9299ad2edff9618f9fe24251886afc65f5c581a9bc86013f356d599e98b8b10f5236a51b48a6b29025983a4\nB = b48a6b29025983a4\n\nQuotient = 27d11481f00519b786eaee96220afd45bc51700f7366fb5e7da35bbc84891aac3d9d2b709dddae371a6b78439fef810c68eef586e1d68350d\nRemainder = 3d1890c5e1555d74\nA = f3504d5d96c9e27a1527725ced337f1cd0a183531642051e166507432c01e8d44c4e8918701c2a05eb8a9d7e26bf04993f9adeef2826ae4e61c602477f849121\nB = 61c602477f849121\n\nQuotient = 10bdeac209c67b023044186704735c7291423054bcddc24b731ad601b49372f4d5ce6e9d85002f8dddf0411efce943f81a5e42cee2d0c9fe5\nRemainder = a93a0c5bd51004e4\nA = fa29e37b0d0410d19fd180149b14f94ec2edccd347da65f6832850aa06a61b7b78c96faf64dcb347893c93c560b8043466419864a382c6f2ef1412873b2d8cbf\nB = ef1412873b2d8cbf\n\nQuotient = 1c9b6cffe44241292320c0660b89f2f77aaadc8d36e33f5ac3da0f12b3c114a156870a92079f7192d237f8bf49aeee6282531c929cc56d75\nRemainder = 1ce3e5eb13ac7958\nA = 144325a641463ed6bddfcbd73e50620a44c606d71fac38efb1c9d2747b4903f7b51fdedacfb66db022aea09b43c7c2ad7b851035165ebe59b552d4f7eee617b2\nB = b552d4f7eee617b2\n\nQuotient = 1b4ad18dc0e634053beb3cf840b53e35117ea06309ea8ca22e37123fd7e1d391c96c792e5125e322c27daa73301024080d73ba3491484b659\nRemainder = 3286bdce6dc3a828\nA = e3a2b90d3ef446f6bde30d3e726cf3e78212324054b40deb0b18fe00645568fb0a6234b6bded6240977373731bb30d1349e25cefd54b7a9985735e9b78002691\nB = 85735e9b78002691\n\nQuotient = 28f5e8da6733240cc2f18e3cf4d42a50d92816062af33a9e1871fa89bdb39a0d905c49faf51cc1c1378741bea34d25ac2c8e522881a6f6087\nRemainder = 135784870eb40c68\nA = 593206f9367b72f9cc59b3e37d2eb23b2061422859162ee53656899c2471017474f500c6e23efe1f6b1e57852cd4229329dc182ba01a257122d76a26aaf9b844\nB = 22d76a26aaf9b844\n\nQuotient = 1ab276448d16c533b6e90b5b5ca266e13ec27b5a58c80b7657df963ec2d1fe4eb1c1d24873eff6408bcb3d0cf97c31e85240eedf0efcc1e5a\nRemainder = 27b105741264f875\nA = d84fde3d851b52ed3b2a1268e9b765ec6c09c5768bba709b3b799802fadac30a6c3184185e6d57249b1c34619f3c9d2b90bc0c348b22537281a39fcadf738083\nB = 81a39fcadf738083\n\nQuotient = 84a87678485b3e60ee1cae3701ebdf0a29ee44115a492c34a0c8e84090e14070eb2ad0abfe2c339f26b5099327515104fe3d1c5546feea98ed\nRemainder = 95f7434941f9d8\nA = f79a0643bcd9c28cc22cc7b4178b3340e4685dd2672792516d6fc08567d2de2d3e25d43f100a58826edb146ac94acac4213bb09bdf8a258001ddd0ab110b89fe\nB = 1ddd0ab110b89fe\n\nQuotient = 516a2ac26e5b3afa502c7f3c6f15376f7a380e5842c229443343b5b74dc3de84db3ae99a0c57043e32a504ded19943c0310cababb3e92cf8\nRemainder = 327cf78eed336523\nA = 17c0d5814e1020d5d69674bdf6b9df193a16c0c8567a589d014e8eb7f6c9c36560791f7acbbbacee7c456eb51a4cdd7ca88011e9d8d9f2d64ab08ad74f7be5cb\nB = 4ab08ad74f7be5cb\n\nQuotient = f0da0beebcfaa716f494cf3fc81fe65117c90adde3b3942e8e66986fe8050fd5c9ebe1c88c5db04cea4c4c14779555d70cafb53870671f95\nRemainder = 3b2f844440d7be00\nA = ebba8c393c2a22b094d824ed95b4acf6875719fc165f73ee6d359e1134949169fdacbb42d5deb8cea96e11e3aac985635b5bcc6c02a6778cfa8e03d9ce6fc680\nB = fa8e03d9ce6fc680\n\nQuotient = 56527f07593774f0fa642241400985d0bb9b41d3dc9e025ca069130d93afc972d75e3fe0f798e127c3e1b4e925000459a3a5a83b15186e516\nRemainder = b620b7a3b752b78\nA = 5d6cad9e26267abb480b2b9ac5ea323bc4c3c53e0de8ce40c89c85accf0499aea5b11703a04296519047585ff12f8795f98da0546c20016a115100eddabfb468\nB = 115100eddabfb468\n\nQuotient = 294dca3b56ce9529aed2c132a9bd6c0c61de7a58ac50582f396b4fadcf7873b502bb869f801a9ab1f12384631cefee72b3e6050a7f69eba4\nRemainder = 53a0fcf5486c7a6f\nA = 24aa73803f270185d23310df2cf3ef67b18d7800bc41aad2ca13f372a27ef0a9217194f3f512e79f545a903895def195a5eb9a1a1b6b3f4de340e9da9b305d3b\nB = e340e9da9b305d3b\n\nQuotient = 16bf4dab1c29bd284c9b6649de65a4ee58f21d6a8b51627ca133fa817872b1a4a9956662db0aead5898ed0eda08511be7c47449638f2fab95d\nRemainder = e7751deb047d98\nA = 77b04d93272491322ed2fe651044e28cadb2ae7825f02b55aeb0f73b8b8a8b336802416fe08c718ab681581ac04d87116323f61f50bfd2180542fcd4a46dcff6\nB = 542fcd4a46dcff6\n\nQuotient = 388ae1c243bc9111e663c0c80495c36e8767bafe188b532b7ac84b5160d902af1b638aec6e4c66955d16bd8ce94ce6027a7bf95910f705ad0\nRemainder = 7c667ea307017c2\nA = 52f357e9a57722a867d8199242e100f06e8df810ee913d6992bfd9dc03ed78bcf44d692aaa7be806df0c9e0802851d7ae8405f76114e6322177907198f85cb62\nB = 177907198f85cb62\n\nQuotient = 33dc2fcceef7dce92e3a9df58566c6e28d03b58ff6ecbbb31e43936cda6380a56788285d37b5e8f11487afd78c39cb2150cc98d9d78a0c6cb\nRemainder = 429a380c9f8eeeba\nA = d99cf9a0bfc347c9631ae8c69defe1f1509c3ecaeeee5dbc61317bb73fa5cc6e704f64c865cf4d898f8a2f63214dbd511f61aa6e09856222432376698f8d2f67\nB = 432376698f8d2f67\n\nQuotient = 18ecac9e5539a014cffd8310ceb1170577cb23aa9cb3c523d57ad83069d1609ff743cd3c275b67097a038b85afcd7105ad21672f9ecbbc7df\nRemainder = 37924fea665f5c92\nA = f87aa8b6e62b09291e0e9b832ad71d8f85d60501a8d89d2638dccd4022e89bc4932c186a198557282527dfa86dfacc2f90fe0656695b61429f8220509f5106b9\nB = 9f8220509f5106b9\n\nQuotient = 37c0649a53c8cab91a7458702870bf64cb1de9fc1c6b9a3b92444119d368501b62d3a5138af72bdb7752eab8af6bf4e3bdb9e3beb1805b88\nRemainder = de179463e3e91ad\nA = 995c04c1f24c4efe88393bab7a7545e39193662d5db7c8e557d6c554ed4367f5af82c463d0ba6bc3148620481140add5677937989e03fb52c0323980d8841d5\nB = 2c0323980d8841d5\n\nQuotient = a6d193cfe7d8983768ff29908ee6e07fee99927a4bc4ef41d01f63f3b4a2e7029630b7d925d0979458cdaa903771286af672253cd99593b3\nRemainder = 6bf69921db298b3e\nA = 55c856daa8110599cc4fde0a44acbd69a68eb177e0438f7d843ba0fb74caab2a7e0c8a6f176f5555779e65c555e9157a16a1497edf36ccb583a458f0372a57c9\nB = 83a458f0372a57c9\n\nQuotient = 63f379bef9866b59f8bfd6bb0120a75dc03506b0034e7440764afc8ec14d8d735aa6f03a568ea98d0a74ab9bbe9c6e11b288467e5f79a2539\nRemainder = 11c077beb8667d88\nA = ff1fc3ea60fb37ff23e2f2f4e207a86e055cca41eebcc5bd6376904b51fb3d233cb04666fdc92be33239b5ee552870e45717890e35fdbe3728d6ff55d5662419\nB = 28d6ff55d5662419\n\nQuotient = 285ba8cdfbf00b112e496ce65cdba2271c82a273b3d30bed82ef2d360790c5deb97f3311bd5eb9876a61e33b3a37782d00c2d5ffbeec752ca\nRemainder = 1672a8aa119c3a1d\nA = d614352268930d301aa4046cd38e2eda4dcfcc52eac984943f2c863de5c4f8a44473a8ecebf12cb8f4da4722d305e5c9c3eddc0109d416e854df334dbfcfdd4b\nB = 54df334dbfcfdd4b\n\nQuotient = 358178128648fa9ea28dcfe68b4cecc7071e129e3ce4d113f5d1e387f7e5a412e9d2dfe5ff16d9987a544004d213ade9c134cc240eeb6871\nRemainder = 44c3fdb374bc0c30\nA = 18b973dd011969e29a1f4a5b8f118313f715c2e31dfebd9fe0957cf23cf36eded89c38637a8d3512bb23324ff", - "2a3627d5b942300200c823d764b7a6c12d1c91b\nB = 764b7a6c12d1c91b\n\nQuotient = 19ea7212f6604d423b308fe3f2f4986f31aea9d6a117a3e207e38ce5bbd8d7a866285ac60433630de547fc84e364c451457fbf864a82c6613\nRemainder = 2718de2dd0796f08\nA = 83577f755a448d5586e19486b04de7836818223ea920465c4eee979a9ce5696ad8e2fd5253b5d5dcfdf355465e8c0819658ccc5580fd29b351169b54c62b779c\nB = 51169b54c62b779c\n\nQuotient = 13e0c5b9905770b60a6f978d1c983cbc84dccfaed0f4222f534df80c7d3d129f5e8f74f19581332a7f6d383915424c71db4ca19bde2591fcd\nRemainder = abf5f6c8ab6ed4f4\nA = e2bf43c91cdbb244790eb165cc13feafea36f5187cc9bf8aa8cf202042efd5441e3822a1164992da5be750aaac0bb11f09375bdfbd4a39e3b682c7ee6ab5f5f1\nB = b682c7ee6ab5f5f1\n\nQuotient = 3919f31521e87f90df3a4463d0c83fa31e3f569449009d307962d26f07d854e8d3f0badbf55311c206bf34e6227949327a93b1a5ada7a930\nRemainder = 6c3802d44dd4668f\nA = 2546880cc6f97fb379afbc4a2664115ba7909414f35a5bf88be2ed5187bd1a24afaf82eeceb0b438d4999ebf9b7ec752236669425bd3cce6a71d9ad67ff2ff5f\nB = a71d9ad67ff2ff5f\n\nQuotient = 121d5ad4115c2768b962e51d09f426d61624e0f203ac6c923289b4e7964e165b34f3dc1ff938a7cf37478d407de251c64db71d3ee629c1035\nRemainder = 660a35e1c1245910\nA = a36d3250c123697adbbbdf489e6cb40be57febaff654ca951c9fa0b396b1714c55ed6e05e468153ac443dabca29de9b43cc0cc4e62cdf24690593662c86fb5ac\nB = 90593662c86fb5ac\n\nQuotient = ad81debaa02f6e60da58b46e76ce041fc4da64138634ea7b3c165b8fbda027eb64b6b5339e70babbb83430d60383c2cfe22029e617fd03a7\nRemainder = 2e4aeafa2ad76832\nA = 8992cd131757ba5cbe54aa58be115723ea3438ddc782a4d1996980b7b312fa76e4483584df744b10340e5fc9e468690cef538920a732a8f0cafb4e30846cad1d\nB = cafb4e30846cad1d\n\nQuotient = 67a71b9ebaec91121a8cf6bc2932b6be01af7954eca69c5202d771c2c2d13683cdf90ec942a3445771ccfe484f947f078de825ea88b3c05a\nRemainder = 8395953f744cfb31\nA = 4f8ada84096198175174896167405b85cbc03fe0642f6b263a70f9a22f19ad6c9aef38da8ac036d409e6fd925023c95312cebe04eb653e0ec473dc8dfed98967\nB = c473dc8dfed98967\n\nQuotient = 9416326e2347a541b777a0fa1b0c35d8fe76c940d24c6f6806d6ae8ac1e280c16e480786478bda3f780ee92f3f3c361574efc2ed5ca98e26\nRemainder = b8ff45f31bdb58d8\nA = 902f5e48b96b9b1fd16c3b21292ed495987ddac4e1d92b2ab10378f2966c4399d6a41eef622a4991ccd1f647531dcd145de4ac99b3036779f9414ed2f4ba7e08\nB = f9414ed2f4ba7e08\n\nQuotient = 403c651b4e571e8301c4158fc185396554bf61d900708d2af5c2bdf495b3cb539b0b9b5acd0d71654b3aa68024961d5a7bc9e2788e6c822b6\nRemainder = 7856ec047cec8dc\nA = bdd6d846983fbf140173a26d2b709b9f31b4fee1eac9d25fdf0ef3523be0e6afb372acab470cfe1806b36d84017ec99302eb9eb5eb2862222f4916d8b6201d14\nB = 2f4916d8b6201d14\n\nQuotient = 1b6d967173f9777cb6194c8f69289b91da731456fe5a1515a49e4463cd906c84f97381cabdf9f358d97fad5d3cb140e3a3de397e7f9f683157\nRemainder = 83649246ade8bb4\nA = e3da80658acd53ada7c2dc57178e697f2907c5b0c64f4a87a794ca7521105a0568a32874207646df3768ee60964b7d1d2e29ea6bf7fbaa7e084eabd4ea553a72\nB = 84eabd4ea553a72\n\nQuotient = 27b8f1e49e404455cc68217a20766590e749507976a3a6de25a7cf2c32593aaabb04d84deba1ec6bbe048a2959ffd747243c396dc53c9c811\nRemainder = 3daa032278ce53d0\nA = ff3ead7c7b27f607d16f1ef4ffa91b6cc28301b9256cfcb0c22b6818371ce648ae8812dc50a86e4bdc0d0b1e5b0d55c6ba07b240886a6d5766cfb3ed0937a543\nB = 66cfb3ed0937a543\n\nQuotient = bf987f58700508356fb6274f64a9f78d455e4c436fc6fcc980ec0800287ab3789b91c29a8a72b16645ecfeec926b6f8242f3c7dc3adb40cd\nRemainder = c007da44faa80584\nA = 971aa67c9af10f70977f600e10f9278b8e66d2471956da38e5f4b3fedce9a5fc7ff42b800bb4a78314c70bb59394d0880383f5182b6c1960c9e5b47ef8e63be5\nB = c9e5b47ef8e63be5\n\nQuotient = 7332104442474715d7c4cdac15fc1731240f8b4dd0e6ff3284a15a62a8f9a071dedb87f2220efcc5839cb7e6933a8f65d767819db26e134dd\nRemainder = ef65a7789f54174\nA = bcea2ae4b1edfebf905a5820f0481b6c58d76a69df9dbe84764add3f49496a5d7005d645eaee3754e0ed105c13a114e6a0eae5cc4efab6aa1a3d3a0050fa86f5\nB = 1a3d3a0050fa86f5\n\nQuotient = 3f6182804a7ff12fe7ed3c8521b55564559b1a47a78e1fd56597b9470e7e0f6e7e48c58bc8841c9d118718ccd5e0c0bf9a08d8e244ae60da5\nRemainder = 398e30aff5bd284\nA = 2b877181a960c5e29ab1b2672ee22539256a82369e8f6cb5bcfb69e5e4a41f782e89b58fc0ef6ca336469ff929729f8492b44f12199f0e1c0afd12b2c999e787\nB = afd12b2c999e787\n\nQuotient = 1a80a681d2c42edbcbde552323dac3a1c03b43251a99b5549da6cb39ec6947daa0d574f0df68512984fa8e269b0b27a5576b3aaccb76ebc23\nRemainder = 378e44fdc7a5ec4c\nA = d37e62f44de27a1418f348139eac5ab9fcc1ada21ea6d7695273daf638b4d7eee6745f54b99a9678cf742d304736ee356f66d16d874f8cc67fae9be5dfd41a3a\nB = 7fae9be5dfd41a3a\n\nQuotient = ee982a63816d56758c29d284c19b9b984908cf0a9ae3f1f926e162a2cae4f88703aa477c5c14042247635c103494d11593c2c3839baf4d93\nRemainder = 39afe3275c01aae6\nA = 9a0b0476cd33861d2fc3137df292728e1f636f6fcba5105f384533723231a3104e7c77df46f7f34a4bdc63d5c67b418cafcf106b26ad020ea547d34edac1d3a5\nB = a547d34edac1d3a5\n\nQuotient = fb3f4a39a661e5c31228a6b7b4c27e6e52d1954e8ce262b98b61650efffd762cf2a1aec228bec5d5787683cad6b2e6e49a0de91c15c81874\nRemainder = 63e5ed36ff73a42\nA = 4453712f56467328401a69d4d749a0771732734a760a74094e50a62a030cb604e735bfe0bf0641754edff94ac0e0549e8c10941255f0f21f459e52a6cfe4d9ca\nB = 459e52a6cfe4d9ca\n\nQuotient = 7af60a7c0f995178be76c070cf49eee311e6d1e3afaf50c8c93ff200c1b3fe742b23259b4fc0b9ed0947be4fc9a6c212d86de9a0f7dbb5279\nRemainder = 19657d8ce516a138\nA = c9c92a31ad0f3cfb56a294c42a26eaecb77edf33ed40a7e6797927a0c996a7c0a701b484741163df388bb082e3daebf4e1b7a99002632d6f1a41c1d517238557\nB = 1a41c1d517238557\n\nQuotient = c890c55a8e2a3105b9bf9344a57a9b9fab5fa1fd57083d52431b695553bfbe7a44a9b6cd1f83958224f351f8511b14215d1648e88e938573\nRemainder = 1bab5b03c372daee\nA = 88341550e470016c7ab600b9f6cb410071a77f907a58cb6da4ce3e955d1e859534c2c1098fcfd91b9fa66926e51896733c36a824c3a20844add94e27f30ca651\nB = add94e27f30ca651\n\nQuotient = 34c240c42da400317f66f5151630493a2f200ee418d5ca3300cab10dfb429c2acd7280bf066fe19115f86db83d8f5b93cda714533b16abfdc\nRemainder = 18cd326996ccebc1\nA = 7e96d7b90ff09b114dd4393e9bdfb13d8ff517681126c566e18dd6369d87d248734d94bd02a1f19cca90be7642822b636369c51dee441a9d2663ec896e1d6c6d\nB = 2663ec896e1d6c6d\n\nQuotient = 10d18159e75efa8204e325e6be830b4ee8d2c07419e8276edeac6cc286488fc0c888300db3ebb5f935aa82654d3b932540f0093d1880e1d6d\nRemainder = fe9b6b8ba7c30f8\nA = 731aa6e2fb2ad1e1f80d7668c7b0642203af24af382abd207a5ffb588209e8b5caf953e9a96b478f39ec03a397d1433998e3c95e382d93376d80cf0c957788e6\nB = 6d80cf0c957788e6\n\nQuotient = 450d1f4a105ff8d1a3efbb12165ca98c67ae70404472e4862db479e03313b08783ecc42104780c9d57df0ddf19c5b4547ee9ba52ea82dd0c7\nRemainder = 169e15b4d5aa180a\nA = 902bcb1904b80183656dcbd51879e2982e2b46a547c9ae3119ffc12c6a003e4321b519289b7f22fad19d16480182d1d797c3045b2d29dcc12167f9ce5e233d89\nB = 2167f9ce5e233d89\n\nQuotient = a426f71cb3d75365cd076a6c35c10765bbc3f4bd317fb83a70083b0f7dc43a4e0b95508e60dc1dedb780e9b485f4f7a8870960de669b73af2\nRemainder = da381ae5c97a506\nA = bd59dcdefcbaecd9292c4c3685fb87d3a94c0f0ed01e43e63e1f36fb65d6c5eab3b584f3d1f76d31458c9f6b4c69869d96e943c61df102771274c5b4d821469a\nB = 1274c5b4d821469a\n\nQuotient = 26ccd4b7be090af22221729b0ca51a5e66435c2d33f8d88f94405f6c0123ccbbbbc8080cd8448a977946019ccbf5d267ac3f151ebe686720\nRemainder = c41f9e7bf20b376c\nA = 212dbeff03f14b5825f0d7cf8a7501db21b60581a01a26d522ee44e7fe69545cfcaaac64dbc76c7e3027ac39ddc2d80af6f3fca1824c6ff6dae90967d9ab48ec\nB = dae90967d9ab48ec\n\nQuotient = 801df28f4fd987b4e980760f4f2625276a2a7191d453095c82aa98a2253324ad2873abae70cd98c28ef3ce102fdd53469b9f01889f3ba8b0\nRemainder = 8e435da582e59809\nA = 48341b28138dd04807e522e341f74ac46b0449fa45f96d7fc586997c056a21eb3c399752a6a6c023509f042cf9e879f397a34af9aa2ec2e8904674f2ea3ff739\nB = 904674f2ea3ff739\n\nQuotient = d3857b72b70adff9b5dec3cbc63de7c90ccd7aab6595339b2de39bd6b9789045141d224aa4e6bf9a06e017aa3edd00e716a771b3f5b97771\nRemainder = 14135c686d2e9f70\nA = c1cea45dd46409d5e24fb7ed7d849dbb079247af2d312e01083754ed07f65f090e4dd50d23a973488702ef00936c5d78af603ec0fdf03dceea8f939c922b1e7f\nB = ea8f939c922b1e7f\n\nQuotient = abe20c90896e261e7d31bf40e7f3136d36b0b78006d12225a4dbef6aaf2062b609379eefe7e5af5bcec17126286f196f1330da8477096763\nRemainder = 230307c44cd55896\nA = 19a637e4f3051be0f7c4d35513bca4a91ca9b8082fe3c73899b70b6805a7aa0458512495cb6ee1ade55ecd5851be1dba96d65202f06bc7122633a0d905017545\nB = 2633a0d905017545\n\nQuotient = 5ed3765c4a777a903e182f7c9ce39d19c01460f389b904c3ce1d3525edf25ffe7dc0f4d9e24f0bc8b7e01bef19c83e74f17884bd7", - "bfabb2c\nRemainder = 40f5346f8775e20\nA = 546578393e914be30581e24508a33f6560a5805dfb1c675d1ff1d6f5eaa7ee638b9e0265f543413e04e3f1f3b0895dec271c9897a48d9ce9e3d7df32c15b75a0\nB = e3d7df32c15b75a0\n\nQuotient = ed73a67932746985465fb0606fb0e81595514f1647c911c303d4d31eb0306e3b2aece07320f6fea57a7071d73150591ab2a82a7d53968a81\nRemainder = 2e495a881876da00\nA = 8976445bc318921f7e12c8d4e8e50596849a1503b5efb65e939c291de136597c05a1fd16137f0bbbd7197df943cd612118d1e55a50ee097c94331c1cfb1e941c\nB = 94331c1cfb1e941c\n\nQuotient = 5dce24b7a16d847b0c43cf365ea20bee9679fa0e8732813e827cf6ef3c9bdb7fd8846b5689ce8b80a7dc0dd05721cb06d2700aeeb7ff04d6\nRemainder = d8ead1ae3126aded\nA = 59b99e5d028e6771d27004bc19830a5fcb347f7ae04c0ba7c49130bfb198c5b16821e425c979e6d2dddc14889ae58475bb52c6cdefecf2a8f4dd6e462bbc8f47\nB = f4dd6e462bbc8f47\n\nQuotient = 170e10b399a4c5fe354b536fe59d53602102f215d5107493680ab6e181f67d75ffd45bf49ffb23cf9269b856156b5ac6b1c5def4ab1abb18a\nRemainder = 57131776937c5df9\nA = aeb35966e2a616762768b7f63ce3aee5e81561080617bbabd7846b3ca03fafaaef83dd05b8d16cef40db0a56f3b0ef6eca5e236681cb57c8793dc0907d9aa30f\nB = 793dc0907d9aa30f\n\nQuotient = 1acdb88f047f9bf679c50ed67ba01dd24dca92103f8ea2677215b6142083b64f9fd2a365499dc8f2bc61e29fa176f7d76b55557fa58e34f9\nRemainder = 5065b726dc6b3758\nA = 15a6292c9fb66c6770a8dbc6fd431d2a4b57338581f78d0860fda90182cca563eb2272a79fb4f5a6fc72c90dc23e8a95713b65988b5b3f9bcec4f0466c1c47cb\nB = cec4f0466c1c47cb\n\nQuotient = add8127c0a27c961203ea0351aed5b3c75aa816e9c2684574e55f55c7140adcbf69d2cff843e5f53c157bd60b43c45c8b6658de72062fbba\nRemainder = 67f48d3584cf4fe5\nA = 4e8938c8cc46d34e3369c5d8536b18c963dbde56020678f77cebac5f8777e0afc62ca2ba4f533cf6cf7561bdce77b6f495bc1b05f1416d1173a6a288012c7c73\nB = 73a6a288012c7c73\n\nQuotient = 688ddf883a0bcc1ff9bd582119c2fea7c059e19aded8c048390a1d8fd7d769666987418bbe0d4cf4b67009a342958928769375c1c0d558acf\nRemainder = a5356d04b64ee12\nA = e0c9e32056977aeca72e229d83f0d320fbaf5cd8bf3e033289f46101c75ef59a854982f33bcbcfd200034e8ff439d669a03fa404e7dbfea822664967d67dd5f1\nB = 22664967d67dd5f1\n\nQuotient = 39d4d94587fd1445f31457c275fd6294fcb69ba155e7da3e6cfef38ed1272d6c95755bca49007ca62cc101b038d264876f18594b8fd4c329\nRemainder = a34980d5046e2ed0\nA = 2efcb12fb55c923f5c6ca7ae076765059e15d9e75240a6e5fc3db92de184143fab1934c7450c3a380a9851846c9f43d67bc199a314e82e72cffee795d695f82e\nB = cffee795d695f82e\n\nQuotient = 145ea82eff186b7db4b11fa1514674fb9d41c698efb33227eb1abbc4eb78bdb2a280c0c4c47adaf4e010a4336cbb5650becd1ef544e223e53\nRemainder = 36052bba2867f5f4\nA = f6a6c7e33fd4c664652d696c495df387b85b132cfdfe34bbd35759477b4a3c052f610df57e49e85720489e4bb8dc923696400a4a28dd000cc1bd491446a50b96\nB = c1bd491446a50b96\n\nQuotient = 35d0c9d870348b113868282aaba22b21ec87cf421519a23b288b150604729356f924090ba038d7400c0ccd4932836c65902b4d3c46a202a0\nRemainder = dc8c7d087bf24b0\nA = 22228c8a5966ebdec64007704a373b0596ae702d62e29e468653b21a890ace2f02c27f26b043f48495687ce8c2ca8092ead21aa250ce0f6ca26129615a2432b0\nB = a26129615a2432b0\n\nQuotient = 52fc995a486c4bfd17ed9722948e9ede1c4ac2fe80e6bd7482fc47944c4337a185a506a9ca473d49073e1b813ad742f19b13d57914888d5f\nRemainder = 75c703f654ad630a\nA = 3473041ae301dd2806da30dcf06b9c09600086d6873cf3ee9d5a0be638849afb56bce2664f797de4123f6f8fe3e12acd32e33a285bb7f493a1cc13a7108327f5\nB = a1cc13a7108327f5\n\nQuotient = 1744946730b2789977620f2e7439641125dd338d1b31fc50813b34dea70b83d209330bd17fd527db9a402ad9752c26b8823082ec9971f4ae65\nRemainder = 453a3d59303ec3c\nA = c0f592d83649bcafb7e2de1a8a71fa863c1f51b595bfa638c8fe30731c6fca36da975b6f19c657e3ca29efff6febfb311c003ec68189998c084afe4979b5bb19\nB = 84afe4979b5bb19\n\nQuotient = 468f3eece20aa9d6473f3c559760793e702758a3d9cc19d7817216392c7cc7c3968778cf2fe0c3f0c1424d7512cee19ac0717952f18aa287\nRemainder = 5904e71034e3a02\nA = 1f0c99a128c757d76ae6dfcd01012f0453c8f89b00476ec46321ecb872f99a48b4da29a4abffd0bbff2b727dfa182652ca85350b4ce100fb70a6a40ab6c41d95\nB = 70a6a40ab6c41d95\n\nQuotient = 12198913ef16c1cfc7c1be13f1cc5991a61ff74935e09f0c46d26456b7cf2825403b9851d07d27e0197c1fa2ac5e32e836979a184f14cd94a\nRemainder = 33431c3df719f946\nA = fbfbf5494a9c5384c7ae3df6c02a5e1f9f32dc31cd7f437832696bba164bae1a9d95daefb8bc08e0e8e637436fb747084460697b5ef5ac9ddec06757dbe61aea\nB = dec06757dbe61aea\n\nQuotient = 376c2f902566d83c21eb7c3aa3a6fa0482ed52c253f67f00d5b915d0183c2d9a2891c2ff837fcb426a4c990c48bda4f90e0bf69d13558696\nRemainder = 31540f5e05e8b4df\nA = 2527f8cafaf7e8319ca53104229199188ab1ca5fe592bde8ecf605e17ca6446414e06898a85e177d6985b5cc6d4eeabd6b222b5f44b4fc1baba050665c090b5d\nB = aba050665c090b5d\n\nQuotient = b8fdd5cd7b2d9295258bd99e2780921cb2ea70627a79088039fc3ab1c62bcfc6307e86db4a7803f18e5339f152063f9e41d370e97b1ba2f5\nRemainder = 4ed4f2d12e4f4ba0\nA = a25bd113c5a8c67ef65aa80f1512de43c9441fec0c41250048d29c406fbdae80912eb3970457d621c552e3af7ef2d6bc1b5448e7df5be724e0adf6f71df7eef8\nB = e0adf6f71df7eef8\n\nQuotient = 5421daac8cdeb6acc2b8b0dd85b592f255ee4fedb3a9e90f2a5bedfb0f9f033d7c562c96958346bcdda4664c67848b9d9fa7d3892bc4e9af\nRemainder = 7e5661558c345eea\nA = 490aef65c81b32f5df76dd58decdec3e3f73bc1fcbdb6aee0c93cd98725056153b572509e75d2cc4b042bbeb0a77d27fbca1e39efbc765adde41a7dfc5c3576d\nB = de41a7dfc5c3576d\n\nQuotient = 156a8a24e7804c5f576cd1757dba44cb4185bc13cb56603b54ee3b70fa35cd98db1992904d4f7d99a63b3a486e6fb31141a9d39cc0301f897\nRemainder = 29e9c1627537e5a4\nA = 5e4a10e772de8dd2c96acd714f7d3880ae8ab460095a01038f3aa9b8ac8165889403b42019a1e70e0e7f32e77fb388eae3579dbcb690729c4671868b0526aeca\nB = 4671868b0526aeca\n\nQuotient = 1b0eff2ff0aeb2c02ee3cc9e0bff808f4d616eb290293b13a6b58a84127972bb417d55e1d001a9720ec72562ef3ea688e64c4f32c7e26cc87\nRemainder = 664d57c57d4952e\nA = 806b8504abfbeec4d5923f83ddc071be88e11c4394168854448df96160b95adb1fd9c288852e2f3df3e36916ba5118815ca2e83a6a7d9e074bef9c961e2958e3\nB = 4bef9c961e2958e3\n\nQuotient = 2e363b13b0457a0e9effc2d7e297df78f35e5d24d0f8ad4525b573fb2f66f374871291ee8a8ee3d15a823b560156d474c678f79ee480bbe4\nRemainder = 5ba8f49e0ca36ab4\nA = 2e1bb261d98ec405dbb068daac5efeb0a51f08149181864e9dd6bf6cfcb617b76d8facaee2ef468807e0403bc550d58e8ad9e5cc0f094b02ff6d0277fe642f44\nB = ff6d0277fe642f44\n\nQuotient = 149a5b1a81b9e47ed36be76252055bb202dc25f8fe7beaa1ce59c279b32941cfbaf8fe4555867850b2fba43b10b74534db82398320f9786d25\nRemainder = 1ef621737e81780\nA = 63de892cf5df40c98de78c755c99e94e0e76cd5dc0b49b8856fe69dd0abcdc535bb1416f0d02b4eeb54e8a939cf7ad4edfb7de4dac87523e04d8ea8637e50920\nB = 4d8ea8637e50920\n\nQuotient = dea8a9211974758752d89965eeeb93cc616f88ce757ec2809f829cbb8d99b4ffdc3f0f643779fc5e0bb53b5273a5b15965f4a364863592f\nRemainder = 9ae7de3edb6c7edc\nA = acd5cebd069f7febc38c318867ba3a562bbf8ea9b19a6b33538ba107e49439f8ac6e880c6267c29b39141dbe2273d93062464de307efdb7c6b738c0bb282c3e\nB = c6b738c0bb282c3e\n\nQuotient = e9149b347cdea84d740be70060b239af000c4336ddf36fd5159083b795c4763588c87a959df0104212a04cc928baf60b0ea72e8cccc6d477\nRemainder = 3ef5c6ee67e6f5da\nA = 6ccf1b8b406e6a106160e73ac4122a04c0814ef5a47708a6776eb52002d52772d3fce3fc05398172bba191390aba925bb23aa1eee626410877822f27d1e3cb09\nB = 77822f27d1e3cb09\n\nQuotient = 1606c2fe44cd0b780ee474a9c7daf0b2bebf62db0ba8ef5a99fe22036019890a4c7dff73e678965bb0e2a6e61d00a74a1d33dc1106842115a\nRemainder = 7cf920ba2897f714\nA = ef9a3983f26237576311a871e4a3df0538593dd0cfda58ab90b889fdb35c700f7d158abafad127605057ca0532e846992c41ec06902ce58cae0c1fe238c726cc\nB = ae0c1fe238c726cc\n\nQuotient = 8ccf17de5068451fef1c2808c62e19997c7f920d5cc0fde1f5a247cc57c6d730df553cf33094b786597a343a0ce9e4bffef568247e904343\nRemainder = 2689c40a54df34bc\nA = 8435babd279b7a3833d01988c58005d4557f7689ea9b7168ef42ce2b31a1a3c32a982aff654f271a651085335496dd826ee4b3bc27f58920f05dc6676e51c662\nB = f05dc6676e51c662\n\nQuotient = a9e78c48c779140b1d15843089765ce9ece3855537ce88cad3eb7aa7bd6ec72df65adacba2bdf6c491066406bdc3dd3dd734a70e93eed958\nRemainder = 53da0b15ac079ccd\nA = 78550cb7b58b58d6878b615dfa25a5b90a1ff631740e631c7f8829962446903c686c810c46a1551b6c1f7a89ae898435bb8e36d1bae24a80b54edbf4bbc9af85\nB = b54edbf4bbc9af85\n\nQuotient = 1e3b41304ee07f6baf1ca061e0e28a3740991c6ca2749eba70d3ea1f9cba8adec45cb69a31cbff22784a9e056e884713c0812e8c7981e49328\nRemainder = 3d051148ec43a72\nA = 76b9453d315e7a9c592e1f2640f5b6b90a65e7f2ff8ac24b9b47e35abb76fa5d303be6d501b341a882bdd9d2a1c81a9280724673f87fbe9803ed5a2e7edaeec2\nB = 3ed5a2e7e", - "daeec2\n\nQuotient = 1921410e1a538a71d33d9c5de95593fada116200c399fa7590ebc374282570477f5f4abdd5166784ccee9671a1a23b96378df62168049f6b8\nRemainder = 1a1f4aeb882d7546\nA = e4aa84f782a65d376b10e7789a7d56695885aae274db6cb37e0a34414397a57b4a5f76dced11376af5fd11d31828203e685861a6dea239789196fe73d0e46116\nB = 9196fe73d0e46116\n\nQuotient = ed2afbd2e63617a651911017d9d02224d521e99275ab642ad1a941827983b17ef0f2067b5405b20e8e97f2ae6099150a1989df94276aadee\nRemainder = 4578107045b9cb81\nA = b547cd987638ff7e3c30fec9b728bc10c3b8cf16e7040bfe0fe9a26e44d2898c4c4d28ef525cde2b4007b2ffb3aa80fc4514a99b9aa2e112c3acc56b72ddbe9b\nB = c3acc56b72ddbe9b\n\nQuotient = 56181509251931afca3bb9dca21eedd6ed4226be67497d8d1bd0ec052af146993e7358f132e842f9b6c4934cf1b4501f5d6c5912e65c8d3ce\nRemainder = 1b9861df51429a6\nA = 32988a4e0769a5aca200f6f6f1498512e13b4904a9a311cd8a962fdd688de0c6e50b04f42cdd2cf8bf9b0a6922657f9ad195773e1250f85509672452618da9c2\nB = 9672452618da9c2\n\nQuotient = 1fa45bb973dd1d2df0002772afba55284a1e41f6aa4b0d1a6c6a4beb8ae00b52e88a9889037b8bfa9b7ee38036c57b713b48af156c3f9e8d8\nRemainder = 2525d52ecdec8814\nA = bda657ddeabe24c82c883e85822941bf64448b7cbb368468078101289b6fca36680b3884e35edc1fce5a5cdbdfc11359a1ba8ac0785c09ba5fe5cdbd30726df4\nB = 5fe5cdbd30726df4\n\nQuotient = 63e21f5568d07976aa81a2690b9e81b76fc3291cdeb010d1693d0e80191186815c7b2f83551a5f1b172640425d4733f06f4df1b2c8a7e6ed7\nRemainder = 14781a368471ecae\nA = 9f3dad0b3b56de15ac46cde1d79aba6a2f3b34d685cc810e9fa3f2d865bea4afb480d58653630319a258e9e8ded9be93cda3bc52b80a9359198221221724cc3b\nB = 198221221724cc3b\n\nQuotient = aae37878db016dd758003b85ef52acc7288b7b74c4723e3876a710baed4751d3be2ae49123b248f2b2c55a5be702c4428b1dba9b8a6ae8a9\nRemainder = 6c754d5c167e1228\nA = 4b93a98eb7b92cea0a4f5c2223e77abdfbd332b39f295b4ac40f71625d88e4add7e482adf3010082d8dd8854cf714a54fba0887de87946e97137cf7eabda038f\nB = 7137cf7eabda038f\n\nQuotient = 9881f551c4b7e67611f37df29e77cbe4e2d9fd5e17b7da3d013d6f3d4312e53dd26dfe3a2a12525cfef1ef81e6ebeeb7ef8fb4f918bf15ee\nRemainder = b14595005716bfe3\nA = 7737f8e7337160c14cfa8411236ca0354d8aeabf389b9fc4b14bb2ec3bb68286f3d82eb394dbd8062862b955e9fc8e86eb646317d1315d09c81ef51b30288cf1\nB = c81ef51b30288cf1\n\nQuotient = 4c8519d4d85ccf845fc5b8f31c27c60f0893ffda29ba86e8a3fd5fe67de5d29cb29362679abde996039b8febda2ecf71f6b9e1c1874361464\nRemainder = 10fae644af084f8a\nA = 900f7846e927760d9986894de6489e53cbbcdd59f7707917e7581422508f2ce79b77bd2c56d964a41e60baa927ca679faedcd9cd8102dde91e1f583ae834b092\nB = 1e1f583ae834b092\n\nQuotient = 16ef17b40bb73063f3cd0929cfe2405ca0ff2d3d426ac05f8a8dfadc85659105f7f728e113baab59247c4c7936ab975c08d6f1c72c12c532\nRemainder = baff11e6961c72e3\nA = 130b212cb6f3d854e4f17524953fd8592f5e59dfe92fc7d955e2899d1dde1ae4aa20d749caa349ca8d1bda7eeec2310532a7af54660e2a1fd4929335a1623bad\nB = d4929335a1623bad\n\nQuotient = 1cdd7ee2eff733b83beda5b862673177e2f2151ee0fd9ac0bf0ec5b7e05516f1d1b59ea754b0483d0e4bfb7668bb99117907a58a8ceb78028\nRemainder = 29e33e0c2a515780\nA = b0131ec2c1ffe9a523591a9453d2fc740bf885e7efc1a0158905da1e646745ef1bbf39b406564cb3da2f842bee307b36219bdee5991c969d6199279c25d4e380\nB = 6199279c25d4e380\n\nQuotient = 20bfcd06f9c54c537ae563e33dab31047aa30a6bc4e7eb0902bfbab3bbb7e65df442c46625c39e08c88310116348e9ebca2450ab463727f90\nRemainder = 11d8f2f6d4c1f55c\nA = cefafbaa2990eaa88184162ecb118d20e5999e5a8fdd25ae7f6248650ea74a8cfb92c58efecdd5d31eceb618f1596d7a6bfd31d092cf86da651f629975faf91c\nB = 651f629975faf91c\n\nQuotient = 37204c5735e4ba5e47e845d8b652cfc2b1dc715abf21ea0ecf5b1c6c8b9e596591fd7a7f41787be1a028c147a721ebb891b0abe3bd079b589\nRemainder = 1ee700ffb0ea02d8\nA = ce22d36b3cb913b32bd0e25cc14c7270d3f7b8e600a9b6732377f846adafd7fbd8a09d12fb7011f2283d988fc29aa25948dd4a0f24512b4a3bd460ee19887d35\nB = 3bd460ee19887d35\n\nQuotient = 191051194e4362bb201f5471d4bfaf92f79b6fbd119ca3dc1afffba334869ed9f8acd14fc42a2d8f616d652610a483ad90f5140e9a5ca4172\nRemainder = 74785b6874d8fa37\nA = f3c79f9a6af1c5bec72218d969620149afe8bf068cf7a7aceda977076665bb5a2c30729ac3aa976c9be379c6a5458f1501db8802652ef69d9b9f4f097027ddd9\nB = 9b9f4f097027ddd9\n\nQuotient = 6c46c17fdb03d192f75d636e1e2ab4e858d55f0f205cffd75550c4347726b5cfe036c6c901782cbe5a04f1985d9fd1dd39d747d25a6a7a88\nRemainder = 9a836be71a24e72e\nA = 4f6cf6e357b4985442a25b5c84e2cc0a5e685e2f5ff71ceba439b81f4123e16db2296dd4333fff23eea92bdbb812daf1d27c721412fa9847bbc9a0bf08879b1e\nB = bbc9a0bf08879b1e\n\nQuotient = -4984390f93e11c9a77880cfbe157dc41d43fe901c8895ac5091c5367a77370b16d42e8cc260058adf4d3fc8ee8cc6c0099804f4c319f15561b0a2b1caa7d703db82a726c9eab569c\nRemainder = -19374dcf21822188d720d6ec892bda2c084e8af84f38012da7029a3c3660c7e813fd4f7644ca80373575ff98ab6d743e939269c51bf62e04f\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 330af318ce0ffdaa92448777ed117de9c104e0f975651322c8e01b1c470f3cfb7a78b11f7daeea57614cec37d18b89155f19babeda0016171\n\nQuotient = 1a56f7d6c06a316a9a466319cbd558a99f06843782673a54775d859768a61933de3fc410068d00d5f6ab13fafc9228fd40ad41434501f8827bd7461441140eb6977f18d102d446\nRemainder = -3c3d566cd48a909292be2ce30f88ebb68e9122a3359f52d1d7b0189c467b829a9f226c0b64845715020dee12d179913ddb7f17da2db86d854bd\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -8e770450768d07ce20ff8f5f6af464b1ee5f1d0e8faaf927a19d3ff801f6089378133e822b8e63cf29c4c9ed721adfc91d3355a3c7bbde77bdd\n\nQuotient = 42131cf8f52a6a3f189697ce402a8c9439bf05cb3dc1cf8bc49dc2f07cef15b3bf0102c941b5b3bde6440abc6eacfbf77ea8da06ce932fffb226b33dedf001e9657464b0f06\nRemainder = 4cd483574fce075404dd22072abe61200fc455c15b382c7f2962ffd82c38ec1e2c60f71267cbc35fcf77fe1f9301d6b5f884f1c416304aa9f4d4b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 38caa64e74b29a7e9bbf341edbab112a730b17103831a9ecb70ef077e9660b2dd1fbf71d7f6bb4cdae2ed7cdbe9070ec9fde996c91b9bca5b83450\n\nQuotient = -11d6883fcd705ac97cae5bb7f8a2929d6f636f4f232ae9a4af9769183dfce9a9296fa0714c3f4fa1eea467a5c96a484a59d0cdd87496b9398e7a818daf89a58add3a39e80\nRemainder = a6b7984fd80d719ffe2e6eb756e4e3bd7ab51f6088e04ac8fecdc744b0385294dd23b5007910109abf40cfca814c10addcb5330e422b6f5eab6efa2b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d25d50f53c694cddd56aadda2654ae5888603b39cdbace93d19c117af5505750aa24e615f95446862bd693f5b444e2a876eb2cf49f6c7acd007eae02\n\nQuotient = -3fa898b02c621915f44b213ba4e80b8e85c7a2f4c78df2bda7d99494bbca3eb2d9354965d83e1c9001f10aad9b3f3ed837a630b329f5a4b28935158fbd9d291a120b08\nRemainder = -320d41a3875da2e83ea9a83947f5abb1a7026c84020e983381722bf7aa87d5987ab088cb2c37fc3781c82c81bef3263fec560023e236a747030618e9d2b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3af2721aad4b18db27842b5e539d8cada9dcd7ac4c5b885065dd2496a6f76fa73c8a51b239b5c068ea6feffda22d8ea806fb488ad5a94210264597edb40\n\nQuotient = 179307c3e14de14a744d082825ed723b996a4e15f156ac473960583138c43f4275b4436c50ef8f21a7b450a969819b81c15bc355fbc5fb55cdd8e124d931d142851a\nRemainder = -9c8eabd36a25e995c1811b79a2a0357f6aeef4477cac0ffdd130046cb2a647f928a34d91d9b489d394965719cd58604b957c693a93145328e5568d33d88a9\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba46638", - "1056a3b92c35d9b8b71372b\nB = -9f2d3da1da77914df66bc889a40847a0d705d4648a11f282e09173d170e96d84b5a45092d995318fe7a954b54b88b784423402519a38bb521e84a4f6c5485\n\nQuotient = 6c0f316406afb4cc2aebe34f7948422de0b612a02dc47f4ae59419c579fc465ceae1980a3e524fdfdbdfad4862f168a9851664688c9ba01a8bc1ac156a6276643\nRemainder = bf52a2fb6493eac22fc8b334ccd8e8fa347620539d9189d535373f94503310a027c5423197c7279bb51ab8c459e27f548d57b55740320e80b753290d077aa7f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22b9e55639ad3ff4f071a49c8bba6bd9047e162fb31882421db8ec5ce46f28fbc35040bbc74ead5a948c47c43e9c7adc32fa52046b53f12b07b5224e0d8e93e4\n\nQuotient = -1008fcb6894d8c411905136fb3e05b38ec5d8df35db06379fc2d6d3e3579bcb34fa6e021b98b899d9d082c111b1a6ac8e50418fcd5968ade6aff8828d8e4777\nRemainder = 3d7dca387b00c677d855fc4af4d86d86331fe4309929039e828765f0937990bffa964d3ffc5d4f2f4b8bea978329e7cedb847c7cc341ee52217f903ddcf9446ce4\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -ea045323f406bd7ce25b3ab4993b5f6dd92ca80e3a02607a862deb13470ccef229fad67ae958cd87fecf4f08d9609595077d0d1360d9fe48c4566e237aa877e7b1\n\nQuotient = -42a50301031962754ebf9c4b1e125e6df3dd40ffbe09c044b1cf4b62ffb4f92d298b05933a450bcef65e86398da80740a610ba45928000a5c12d26e9f6a4\nRemainder = -c5485b82cfefb3f980e0fc7c6cd89b1345a8fb942299bdc36ed4ff8916016315a0da84ca0ee2824dce3c7e5ed49d517c45173c9c8e30b224940af6cf828c73db8db7\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 384e523d5a687bd1a90101e43334894b6a27e8c6809a8bf5bffabc34d558a8309997dd6f2a3b7c1a63100dcc0b6647b444ef7e5aa4a9c52c7caba1ebd096c3fae6f95\n\nQuotient = 1054439945ccb5bc5461fed04e364c7a36d5dd2c0428872676debe07654b2ce31e435a90c81f2bac1032143acb0c49ad101398feee8426bf270bdc0229\nRemainder = -7bf919e14b2559ab82b3c1bf428d083a4c851a7a1fea44718377e9e945caa5cf48e0b1ad727e251bbb330292402a75ecd96a56db4ad07146533a3ab5a717d0a25a3a7c9\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e5cd83a644ec86b94f5e33d4dc307a2f14ee8653288145dabb2b5f894560c164470197fb9e37749656f47df343c245258627aeea17965fea10a57336bdc6b4a47443492\n\nQuotient = 62675274798218da426a54ed7158f8f737b7b3c328a9c351371f0cf61f41712f9b28741f187eb635ce45866762fb5fc5051776151d202e2556c5845\nRemainder = 1aeb5d1fde3c259917e430e6790b00484d0d9508391ba6ebab0f6299190d4b34f5f7d8ea2174974471a1e28ee2c15e05da645db971f699d5d0e80569b7eba7908ae579f5ed\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2622350611b486e6be7a7c1c073c230d604d782c2696038a3233ebcc3f01c6a711969094e47f49e294f2c5bcd04fb1b7c0934f19bf6e7aa519a8d4ec2c172ac59cc1a57b26\n\nQuotient = -12970cdd96b92c37787971cd8dd166999ff241be881eb9543ff29165a9c1a3beeb38b1910a5724ffe2b73ab95ac1ca88d3989aa531374d4ec6122\nRemainder = 627455cb555398150e5b4c1c53ee16dac8d80d9616ed1ef40031424287f8028a9cad1a10bdd8430f6f65368cfd00390c8d4355aa5ecdbd1ff0266a1ade235f33cb5309446961\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c9dac93cfb7abaa3fcde359e09a92ab0b5c06359bc09ae9bade3c6783064dba90b233b4c8d5c6236a13ef96c7a223e37bbdd931eae61e845e5a10088f75b3ff5f1158e833b15\n\nQuotient = -6742b3871dece5986d4e219bf5f43c101da8896f247521fa286fde696e0b71ffeb3b6a3e4f33710c9ab150b7a1f747cee76839c5e7f2509f62\nRemainder = -203b2d6eec9d485f7b439fe9d4c640bb31170af38418faf4daad577c30e44ca06efda55ceea4fbd959b3809fa2002b6e2cb891decb09334ed89ac66ff05502036b2155ff62f8aeb\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2457088096865cd052e9cd9349c6e5e34e46c89d6e860a36f8e2a0bb1e5d983e07d05e6f6b31edc67e4793cb4d40979c029c80a13e654b66c8acf6b894f615a3ac800bbd09ce020\n\nQuotient = 15eafc416460d757d0abbda8d094eb535262a71dd033c25e704a6df54265b6123247e5625da476e0c220ba88582a1ed94265135bf8bf1fb1\nRemainder = -64ccd9a0ae0b0abcb5507d51b2e6c8e52e67907474605c439796febda06eabd8a3185fdfc0bd088cc49fdf564b5b45890b07269c15b1aa2f993cd9872b97aa6cc37dea2f03444b3ed\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -ab34d3906d8a2b806b22c73d44948d703c1e05a9337f75cb0b5df5205c5e2d23f8a92d8381372f9398c9ac2f7b9302b83e48b26512ccd0b06e6b8ef1b930ec2678d71e2eddbf7349e\n\nQuotient = 3b22916d9fe3145fcc3b8872bebf5aee4e14235f618e0aed09199852c6bed80df39256d8407d334c06f4479f230913370b7d451fad99d\nRemainder = 1b02a7b97f9ac1f6306aa00fff0e59f55fce463ffdc640364a950df29474e08b67cdfcec0628e973d42fa1e4f98e988ec4c47e4915651a1731b71d5e36a10a0d1b3420427dbb79ba7d52\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3f74cafe9ab0c1b307cd7571fd442665fa3205fb2f45b3811b92d1d38b096a2025b8170663a29c52ca84da102e62048e583fba96a594c0b23952fec587814857c25221ff2cd0533cba6d\n\nQuotient = -12ffa4b6fc369404968911c17358012b993c18c2ff34122e06f450d3d441926b5f5638b40efb012d76d8bcd3c0012d0a0ce5d55c596\nRemainder = 64548684fd5f6c816bd296234740a4eed772570bd4a48852462f9cddf14f1350ce7c7c6a58aee8f66ad7df87927458db09e3af08eb5376de08444f35e5171cfa0992fb27f70b81574f6e8f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c58383afca9e1c480ee75d3cb6b0b99ea42e827d39fc96bab6b0dddc97e3eaaaec02a74847f9f7d49937f5ade3580bfcd491990737d172d4079437067251ab403c36a9826e974b113e2d2a\n\nQuotient = -4964410c2b038573107b0151b36177cdd62495e0dbef536b59c8aacb8836bb45e7bb014e5022360621e8e82a273d0d462b8eb6fc\nRemainder = -1250c42f8c9b129a5c477be446b86356edd1b19409d362c3a5fb5d59c30f1c3fdc1424a88a0d6ce20bae885905d98c8a5a6495931f73edf4c60112ed78834e3bff6de3ed54c867fbf16a1cd53\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33212ef4a8e80daf1049ac6f639f8e1990142ac32f7ebc97675ec90f8eb1a2814dfdd295ae67317253d0187ad33f3932a3a7efb056d0a3c87d28e64e23e9f1de751ee6f0f61c6f39d08d72f0a\n\nQuotient = 17f77efddeed52ef2e423bc2c10d2ae15c97384b766f4108474964c2a44789e61249103d9f5fe00b4d612772dc6ea12a42e395\nRemainder = -1ec95323b7b95169d5ec0667f3cbf683e98c15dd0fe44df4ed9de9586e43f1f69337e41a6d11d889452665dc0b03cf8d9ef2effe0b350eeb9f6468751b8a2c42608ba2a33192b770cb62381a966\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded49", - "9ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9c91fdf2dd1827ed103a102db254630c278bf8b47bb12a342a92f081acbdd8ae5f5476ae194e24b187011ac25b19fd09e6e690777f9d3efb6b3a32c8f5905e1478a27fe4b1adf17a70abb4e7571\n\nQuotient = 4f5dec525ffc737094f40d27446ca0be5b7a2aff02d51d99609165c4cea0dbbc1d92bc0a8680782b616c149bbef7f5ca912\nRemainder = 1bc84ce56a9a0c74962681c02ac927051c81f3824d9f3f0f91465df333ecdb449473d9c26ae3abb9509add5795e89ba5eba6ec7c89b114c86e6991ca0c185b34d6e66925a14fd82809dbc4936d273\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f47be01e6dc6a86097676fbd472c2af0c83a2f743fcaa885e44fda7e9f350e9fb7a8cd07fda59ccb7963f1e95e6a1236f5f94939decdc85afc0e523c711b24641c844cd3113c17fe35ca988ba407c\n\nQuotient = -163cafed5bcfdeda88555f30bd4cc2da2cefe2bcec9a7c19c36ccd04a45121a5a0dc28d0bf6ab7fa4b78933c47a5d5286\nRemainder = 93f856077f5b2907cefcddc4d767ffeb0acb7af64bb9dd8a15dcfdda6c244c24fb8404ff9ea2fe1dc337faa05930d33cac4f61e171d0236e222374cb3da76396ae1329a407fb4ac652fcbdc568d0fafb\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -a8bfcac452a5e48fee9132b73bc2fef771450143ab80aabd8690ce54c9b52c2b5a669076a7a35fa6d926268077bec6d90b722b5d074f28ce3843fb0147e567c45f4e91a11416c082762e71b5c6129c08\n\nQuotient = -617dbaeb8c6f9d584e8eae923c872048f9f9bf039ec6b50cf8f09c061bf79acc3311b37c2502e560848c05ab316fe8\nRemainder = -1ab4613767c4f1f7d127e848f2bb7c72a3a9e1dd6173b63198b80d3bbebce6a31494f19b53ad9e3a77248e6f9b26fc59060e2759a20dcdbe785297bbd912da9a1819527fac550d64bfd20ed1f96450c30f3\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 267d9397138fd0374a7a58593d41627ba1203a646ec2c04997acf607e9d217b8f40183d2f9304447d6f7e727a476e636ded4697a5ff30a9ae3d249baf97969658209c1b32ddc0edf920b0b278e9b5464313\n\nQuotient = 10ad85703fd51870306c5e36b51512341d6d39e0bac47a03732787b2f62e49c76666f7f49b2596de6cb5c5b2f31b\nRemainder = -846b4479713bb19ebb8c1f1b75d2be0f39fc1095a3d2ca149b5565146bc19382b86e5ab0d098ab1fca1ce701d582400190fee34b602845c3c0c498925710f0b9e3af2412ed5ead1fe03d77e9b2b407ac83823\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e0ffa4e120f2f46fd1430b6022fd03f71a22f9b120f8d40e901279be235b32d94760fb8c2403d23cdeb728ae73e2b16af7322d6ebd5f5673187668c99805e700f1e997423886bbcb851448dc1ed4cd66d6598\n\nQuotient = 41567bbf616ab41da51108d7edcb5a8a4877c5a8663b3aed7559421b1fcf4b535a54989efedfcc935b3917fcd\nRemainder = fc026e554a0821e0d36b796fe6a676fcd7383a55fd6158d78ace4edfc3d8aa87c65f0eb41baa2aafadc51218b0562ff4b5c9b17bbe84afc491d9e309217a5138ad48dd51e1b1a9aa51d69963b608ec47d63fcd3\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 396e9b45ce43d3f89386cfad8ddef4b483ecb5173234530c67447ab74629d246c18b9da09522c77f598957e3fd2a1c0c9417399912fd547fb1023ba6b90d63d223bcbf3e7ba155e51bba7e8635aa5c39d2b9dbb8\n\nQuotient = -18f1f395347ce8df530d9330c61c0e30ac9531b50a0af2ae7809db1258285c15ba7a436121287990fcdbda2\nRemainder = 51417b9e9995de34316a66a2f70c146df8e36952fe64124819607bd8691a465f4fde98e590dcd56f0faeb95d1b67751081c2393626713c27ec2a2123aec2a4ec3761e5ace4aaeb612d46e52e16d72a186d2ec8a7ff\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -966dfc779cbf9c388a84e947d1128e2392399ff45d9491259c7cb19589154f82f41e852e0c6bb5a728f6e87ff4ff95abcb9b2b57af1b6b7fc125497775ecc1338e4bbcb5315f7afde4e283347184b908545211afb6\n\nQuotient = -3fd962e88dc1d501fe9335fff8b6b2d50eea967c3035a3dcbcdc9599b81f9a445ed5a6ae7413b8865fd4\nRemainder = -97f06f6155f8d0ee6850728192e0b4fcf55fbd9ba982c5f1d598ddcbc4e1c4be0e209fefa6ab3b7eb2b4c645e4dc40217202285ab0a7270d085dd9d4fd24e5293faf6797b4c3c79bbf3ec63fd82942549f9e8f862297\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3ac566d6b2d18572360fbdc626ec488aa316a74f33d71a17a2d0e1d2bf26395623eb91dc4abebf2f944e9bc3d669fae2e4332088e9ff9d9f43927a7888b1390ef60f05efd6e63ec606ecb3e164ed6dbdc9d088586aa71\n\nQuotient = fb5ce21bcf28490afb64e6746a1a81792c90eae17407c0b4c5ebf2464eeea43e516be2c615f84901d\nRemainder = -3d255bf94c3d610c32266fd472d070c0f5e7dddb88d32723b2e1a20709aed2faf28701e0d0227c2b33ecfa9e708e5ac354a97be732b786210d86f1f05d191513386c580b1ad1f4ac6890f87fd0d4270f23cc5c2064502c6\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -eedb64a6e204ee3d6df508830704f1d5b2d2e627698d38a114c07458ea0befd593a80dfd2e08fcb1893adf57061ec4fbcd3130692de7c46f5ca51361e9b79bb7a91963618b8e5b7591392a5f0e3be954e8b9978c97f12e9\n\nQuotient = 6933a3123d0b32693351a834751345300c49324b861a663e8700bdb3b70ad996747b284a8ea5c02\nRemainder = 13849ef93cbc77460c3c496e8f31f7e01a98c21cdfcd6877547161f9601680665b394933d3a0824f0d32854508c89f0e4a0873280c779c7ca636cd89cf6ee5d42a917b4f382be3b9654039f623c11b43164827f870fa0f0781\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 23ab6042240a7709d43de7ee17332a9710bd0d913c42b3591341527bf48d5bc30abb962482292d45a15cb03c9457cc8d78d1e00aaa63358427b000e59e4260bfe1e2cc603e175d7fcf02bd9f61fae3740cb8e10a510ea3d1d5\n\nQuotient = -10e67cbb33dc6e24765893a047252766c2bfad8385150689dd4fec9ef495dff63ede1fdf78bb6\nRemainder = 9dabe2cbc734b910fa1bd25616daee5657d25b6e4dbc2cd93cf8549715c87974a8336fc5070d86c11f6b670d4b3bd5ee8ae3af2bb321fbb4f8fade3f5c6c2d6c366b4d800dd13ce897f13b0d3fb79f1d9ca525b4e7286c56ff29\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -de093dba98747499f2876c8b6b7a6b9587284835ae35f0716dd594c826cdf5b9179f2c6b08d800a77a6936602ff2b64ee0b7c94493bd5009633f5bbe423454b7f018ae96c21230510ab4bf5db394ff153b0e9eda3ef90eb4c253\n\nQuotient = -521f5e35300b9ec2742ff472cf61235dfe2e449772afa638b1adb812cccf269afd164b7602\nRemainder = -2ad10e8758e1d358d4744ad344ce319617027107c0b8db195d1b58c6e6035450c9b377f026fdf9e5737750af5615cff2ac3ccee623c060d779373136d48a735b353d64bcc5f2e6ea1e46083fd799b5f57dd5ad0ff3e6df9764af977\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2db1990ba1e353a1a62de1b914ccb691380b6ea937c13621a29f0a40ecef460cea52cfbc77d98706fb3c9939ceaaf962fb8003b0cfb40535e0dee22e8e7d04b5648fce2e58803242c199421cc4b26cae776d3603f2ce410d", - "dd1e0da\n\nQuotient = 1d45aa6fe6837a1b7ac95efd55d1690b66487202949a286fc85da7ac0b50b860215e44fb\nRemainder = -7984639b596f1d4e6efea9d8b4719215588620ac959034b303584679a44fa84a4be0c89fd2e29f54e62959f9b7a858c06b0cc051176af82d4b85e7334555ba11c39e6cfa1829995c383ba81dbc220e527e90a1d440c1d069703cc1370\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -80316fdc405bb002990d3ef7d0e98defcd1f0e370d1e51db2d21ecbd96230baf69d00b168afcb7b8da9edc3ef7f6621ae5c5a0d7797e5c92283342e42468dba1036fcb2ffef1f493ff97826477364f6b5a41dc56d6389a01b83eee041\n\nQuotient = 3c0c3f7a777e611d1bd0d17d669a1ef7920b72ea8de06d4b415a73b836e37d6cf0780\nRemainder = d8c77134a75584ecd5ab29e97a909ec139464901f9cfcb1d3d9e29a63d204615b6845d466c8710873980f107c40ab54eca9f8933ef6d726f9bd0f3e9e97eade5eb1a9bcaa7b01b6ad51ff3ecf67d6e4d345f128e990494a2db434fcd3ab\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3e7dd961be36c0c286eb9e78bf3b33e6f9bdf2c2137a0c660f1d21dea31ac9a044e526bf47ec8190e137a60f1f55e947046b9cd04a2485679e48cac80a1bb064a915208889289d63a6e338cf7069ad799861c31ec6eafe02a4ef2c2641c9\n\nQuotient = -178d749de2dae3a2ea4898c59aaba98ad9f340762040f5aea13cad45a793f1256ef\nRemainder = 6c5d9b19aed9f099255b6e3d251aa50d1e534e6c86d82eebe097dc8dd0748201e48ac62eec070a999c21f5c7684e5a700212e9079b5fb731321dd1e16ca82ce80c1f5c17fd1720f1353bb90997f47f5fce335a43a6f59facff0b3724423393\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9f52ead13916f9807d0cf0c6699578af52c54816828f22de62328fbd7b4fd6c3740ffc82af4e24892092c7ecac44b5e775944445e6615fce25610984030a345731f944128f5734e6e315a0ea97aafd7563105695d026880d065761687b75e8\n\nQuotient = -4fe43bfa9417839ee408b254603c3dd176653b6915a89de5b781b400162fbed6\nRemainder = -1c15816e03751a203ae23c48965c8541849b09996bc81d28e28d7871fa87d1c3b2d383c056d3084d7d01d853bebe270fe2c0839e71851e169d417c47caacab2aff8a8e05f65dfb20eb17ed8f67475702fa83087bd868246cbb885d52639797b85\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2ef8419306ebfd215d9079c7a2b959a53ca2f4553845e3cd32caab2635c0e77fee8c5c016c121e3cbedfac57f810c132486ba78df9e719a976e0112516893f14cf9b89f95a89aaabf31cce509ac8e7e62ec3833f0be4336afe6d7d73518141d39\n\nQuotient = 127e8c06e12943017f9dd57ca24dca0ead230092811d307386c81b6efe009c\nRemainder = -24f3431858d5aee412443feab243b465b849f5dc97e4de4db88c7adf774d9bdda65fa0a28cf6b18eac6078b00cbeed2ac406f8426aef868d4b59ab045825d4b0a18af6c9105e32abc72fadef55b221278d329ff6fb9019630411bec143c4156df7f\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cae6399216401dec0f8ff5eaca884ab061469082ee3a18e49e0b4d5f9cfc98a598c373249a8ad2374e0b3de71370e93a98650684fbb931aa5d8b4482cb0be142492bb71743c251346df66896806f926a4a5dd4c16ca3294f01bb998835e6583d29d\n\nQuotient = 3f180694e59df85f48ac02b6d4faa26278af9641db18d79f198da5d802f\nRemainder = 36cf82dcf8c7ec783b4de68e0627a4a4b2a508637c176de09feef62dcf382bfa5d8b88539b5ca2cab6cbbdbbd0e54c092f00ee13f4a352cb570034cb0a012cc0fbdb6ed32967f3b81d146f352139bd3d9a5c27789468b7d79b84d6a8f6085f859532f7\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3b7983bfaf565c5ca444367654a07b8bc2bf7fdc04ef12128c392bef2f6b67d9475b4d2f0ce1c380913aa98616fbe1d74dc5c9d64df15f5c9b87a8bfbcadf335a6e8f863c7a01ac175a7d79645ababa5f961fad7d1b9926f7284e254fed33765339e0c\n\nQuotient = -11f635baf7b7d613e84dc38978a21ade2f4cd741d0c4f6ae592d93af9\nRemainder = 4317c686dfd56216bc4865f8dcb6a3446e13d8b33861e74d6c4a3223c387ffb8caeea0141049898609ed1abfc2adbd21756cf64a72272aab6c0b8f2177419abcbf9086635dfbea80a7b884181f2f2ec9a402cb0505e8208909fe062d5e6dc7094d66af62\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d0ea50558197566f22704e66a70328cacd6f4b7ca9b00c16b7c4b4e7dcbd47c9b2526b3858ebb4de7a571ac570872f3b44ba1fec655c0778a8a87ca24851f6072c5c0b7591b5e67a8cdaca78fa46f201e02379fcb9a8470e4a4971acde36cf501d369751\n\nQuotient = -64a078497f85588d3402355bf3e83d25ca1f0ed2c24a395ef6de6b\nRemainder = -87fc31ac66a24ebd629a26209ccac1b2c85e52dc83c5240269ae5a27333f33d31152c9470efd41472af034e8536bbe94b0a49e892b1d23db3c13fd84b7395d7e3f19d7d4cb4a4c07dd1860826696cf7202483446452aed2b4980388e7eda0ccac792d77a33\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 254a85bf512d9159b00a70678239902ee7e15ac2790ce5747c4a4743c6a0851e6a179b64c75acf312dd37a7b82a729246f79196b8a399ff476c48a05f89c29fb106bb06ef0300c4b330a7b2bcd4ea1e82584c7a96b99ec2131c885c5851343cfa6ae4d384e8\n\nQuotient = 116a06b1d38067cef9f55875fee1254c8ce39b42c19fb232a287\nRemainder = -c15a797fed3810e4f536e9509564b2142ffbfc0c961ee5aa923d43a824765c05d2a99fef79bfcb6310c77a91d9bc6d0762bd687493865de270c99989e891fbf6da7ea5c7c7a1032449457eb73222a011bb755ff44e4bdce8e86f8aa9f687840c0832f7fd8ce48\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d77c14100d19fbaff6334ca6aa504001a1d56f274632dc89d48e1d517935503c26b60c047cab9e186a55b72439761c884f63fdd2a38ca1acc653f6ccbb4b7262e6215e6d00c8829b448b7ac8716fe0bfdbf8088c8c61eee8f8db43b7b5551f6278081ac2eb1c5\n\nQuotient = 6fc9533f6d0e6c55494cb1b319ec47bde8e621aa92d91155e\nRemainder = a1a70f674cb141a896c4adace0dc58cdcbe2503fd0ad36ce348dc5b8afc96d0f2f8c65bbbadabf2920012798b7ccaedbe8d896dd2674082ad3cc75b54c5c190ad56ff34e8cb5dd29c031656497d48571295d6da396d5f4cdb652732d874a79a674d06a1d7b979f5\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 21917f48bb8e65646c618068fd9069c06e22ce8c679a845f9c4ec843849010abeee12e2d3c61fb963297abca30813c446f2ae82e909ca6ac7839fb58974fa65f3b5d91fb8b3f99d948519ed56653d50026d694060208cf48e3c757f64885b4ed4328c6f071e9f5d5\n\nQuotient = -1abc689fd19523d2e295f260d248041bd00ad3009cc7581\nRemainder = 1ab5af1478fe7373d012befb319b53ff9e36899c1749ea763fb74f7d24624e70ee78faf3115c2a423629528f45295e4adec7b122b993b5c29260558be4831df06468bb1c63e8afcfb1b9b533ec6acf754563d2ae25e2adb4cfe5ee3024611e03a156484a130ee01f3c\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -8c5a7b6bc8ed6ac015ec24efff607b0446c1b736dc8b409e2f433e69d0ca015d70c64b4c924175d0e0102ebc3e1dd96dd4d5bb01cccad229e699f9d8f9ad0e04339d70cd113e93d50c10c03083a81264396", - "f5db2d979d272798ed30efa15d52289d0c72f42582ea56f\n\nQuotient = -4aa210fbc0457fa7366a8aa9a3acb3f9fce812303ec9\nRemainder = -737bc4fdd3d5496fc7f936ccf14bfc3d93f5b7caf4718c444db7a3228b41015c67aed304fec7704ea8238ba6cccb1e94cac3bcf4764a44bafb49e5fcb0339ae44c0114cc304b9c4370363657cd2bec09bf962ccb21f6091b081e71d2bff8556600576e18d4f78fc68b12\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 324774e49bb429553c10156e8db122670d6dcaf6ef5291f515c517d7ffaee36ec5ec5ccb4d12dff71ae7a05bdfbb03ebaf4dc6c4e8bfdc165b77cae20153c27d53bf27d92ff25643b4888cb586e773955a1c02ecbf0fa6958a8ec0b832332eab2e449be6e72c48d2f1ad1\n\nQuotient = 1c8631a18d189f1fb689f896005f2dd2098e0dae9e\nRemainder = -1a1ac9612fc3354056a5378de5b315f12591ee71f0fa9d8a6b2ea2b1c4eca9947e5c4f5ed3d4b78e69ef7a1f5a9894b9c7d85f6e2244ae76881eb06584eaa98c78b60b46084b517f4882758691f91d9e2acfd580d5e901dae14ff4a4fd6b0d7c73450e4928fc6f02fb5463\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -838df2a27bbb033fa0e581073b879d6e8747fff38539801a1870f2e52d91bc84cf10f2560e93784650fba080304244dbfe9da679f207b6920be46b0214a1e490537e56d99beef3f58b30f311a12283501ad79a5407ff209d19a6efd0421aa144e0cd427380d89bfae5d1f5c\n\nQuotient = 4213d04b9f0b30026bd355404bee887b22b2cf9\nRemainder = c2bc097d1c20f050e88912f066b658446cacc7a4d510343a8d88ed007a8c0cfd5d44fe5f067a0e81536d121b39f2d0feb8dd053bb5632e3f9c04be5f6bf4091d646860cd38c96271cdba466ef8b7e2377a51d5669117e664269fe3c08a51b10e1e019ac063d670a3c7db12563\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 38ca0c2f03a5c56676a2f95cd7a69d4aa2085343af6b1d2a71e0d1c54157ec0e8f9125df2a499cdd484c04feb23b1e0042ca908db74744584036c79f21c25c40401d551a65afed0ef35f1ea000fa1a99cb29e6307f6ca0304145f7e483d008cf9efb028ebb654115a8c6b87a08\n\nQuotient = -134e043b3b88b31f89ff4bc709cfa1bd2c1a8\nRemainder = 99c1c846cbce5e9a26c5afcc0186bb1e43b2501ab3205d13fdf01dccb9b1a935bc1cf8adf74d58f1c316381577366b6d126da49991a0d5e02acaa678085f335ff8b8e975e5bf2e52a05488ebfc21a3e0d0bc5bbe67442f77bfc3c1f0c03b7f7ce42bd0fedd8a498f018d8cbea47b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c261a6c562fcdd56e67fbd2b91027f17c95da43175eaca6e4069c16d240ebbd240582dcde953eea739a4668fbfcdc6af8ff3ab58674c95de90fdb43f64a61108b030d644a44b0319b912bb563f61e520dca9c88f411b32e99c872cf00a01f5badad584636352913b7429b99ecfbe\n\nQuotient = -448c4922b7a7d5e1efec2c3f41d0264b76\nRemainder = -2599e928027d10d3a11056eb719768e5edb1a625fc0b8a1dd4439ebd30a82bfdf89e617ac7c71622058cc64ba32dc242d96fe3ecb856f1b146f831334af562cf88139a99410dcb869b9ad6ac4826563b400b59f55d8fff262dc920fe525b12b2fa167ec237028a098c9117cb77bc3f3\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 36be11eb72832f8ae7b6bdf689f794f62cc1c885e64706d14a77a11df9761c2e9cd81d8f6a0ad0cb1696c69afd80c8bb992cda5100cf1162d600515568b9dc9c81a518da9d240888d4984df65c129ac0b4c557b4e63ee5be79a27473ff5bca58e559cb04c4ac93b61545e7351bb6514\n\nQuotient = 152474a1a76700598c18d9301866ec00\nRemainder = -274a2f9e2bc5f9d75f9897b28f840b71bb10a3e4e7a35ee1dc1150be61130b4e0e987e8742c5edb75a1ce3158eb8bdb7d657b8ba39436d7c88fbff160c7488ddff2f13b3b95ffe149a3d0d2d406b1737a7671f69c0e5d7074a151cb2776b2d13ca24bec261662f2967fd22339ed6c3f2b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b17c79a31d5085b49793b6a6d628109a6047e3b1afc947e5212d0a9ae32b1955cfd6fed07fc60634ad15f32a9e402d7d5f750fb6d1ad958211f9e8ecda8990689e5212cf72b24e9b51bd07a6e0477dd4c02381d0ab6c0ad3cac1f620f723ab004880800736804751349f6bb19d3db48da\n\nQuotient = 5665f53d5a7405c83a5ff382ec376\nRemainder = 252d055186ec896cb3142c9e4e49c441e2ddad365b86ad21ae4ef1c522d3306c2834d6993a5e1f8c64a1ed582bad8ab746f7e773fc004b1c47814f73560db72f7237ef6e2f671d3b19a8777be2e4c662a76db87ea64f32c48ea371b1ffb15df26726854a417e18afcf49054c6d2e0e337e71\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b6eb2caa3ca650be02fa199e9ea6c48646a76434e268713753a547e49571f9817ad396f2cb7b16d307801fc8892f0af3e7f93ce08f7955a8acfbc0b56add4b4c7ef7351f60e402b9a8ef7fe02ccdcb4b00b7ffe78c7009268dbcf1d606c3a1b5307d9a8ee6121c6a635a742b8bf36b56cc7\n\nQuotient = -eeda035247bb13860f228d8f2c\nRemainder = 3976edf710ab42bf069e5829de7e16962d1b765f6ae6ad0ffabe723e21ab01cb9f3f5f4edb1d8c13cafc0556c0aa93d72dbcff754ae9260abd294647b71785bb049bbb865a26bba22defc458a14af019a796e942e77d03484028aac2b3798fa730ae0193d89728bf80a8728715a0807b3c497b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -fb5e55f261aa96f54983869d58b3e9f0757d363b9c43aca5580b7c0380096f396ec79d1b30037702c19be5889fc6376793cad51975100f33ebf43e0897dfabcb9adf3adf8d845aa7589ba1f6d155b25f73dae3b2f835595ad6050401fd4e6392012d06194af415b810b0c10a53bc56350bfcc4\n\nQuotient = -5b37eb0c3e3f8f8d9ac6f4e4\nRemainder = -28fde388257b9a11441c592580cd38caf2d69e2ba57d43151c77d26535226e05e08a9e6d8ed470d4354e9f46b7626e5f2b22b652a2d78f817bb51598c727a765941fba63510b58fb3dd5f30717f237da43b42d20bc260b06d488c9c912bfcea1e7808544c58960a3e1355c50c889cefe75d4d9937\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 29232a3fb059242cae6e0b419ff13c479048cfe46a9063188706c6a3842674b16a1aeaf771c5b0ef401d2dc8a57f6fb4fe1b3c7bb545c18ae763e39421e6a07c4469d234f9fc737ac21ca67a5553c7ed693eede4325dbd132dbd9889d815c02f426801eff1f46e7a52f72845234acc6c153f34065\n\nQuotient = 1c7ac058af2e7bfbda9484\nRemainder = -54d7aa6dace87e61e24d87053b9d094bd160916b720d7cf4f740a4fc5a7f03909773d0456c530ea0204427146fd44d3ecec51d8627b5768de1494bf42081a8a4fa97163b0b93b59e70e533f3257723e441cafa4aab471ec4086601021c4462e1f74bebf298ef45fec98fa8e6ea97415f84c93c12633\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -83c2cdca7577b32c20e9e20fb498a2bceb7174ea9aca09d4dd2fc7a1d3b922797b4e9640c7eb9dbdb4d93c7fb9daadd680c1c7645d8102d77e9c877a9f65b13239f9a650dceefc1fd41ea9bd2b38a622bbec99cfddbc6e88f377cd51cc29fd17a27f3d0d970403a2aeeac6ff9fd69c3bbc5c2b0fe7e\n\nQuotient = 472df5f4393f33cc382\nRemainder = 16579a289cc776a47611353e158c43dadf0a78833396f8419fcbbe47d90c7e840e2c90e73e563e6c505bfcf691120ab0f1e9ef9c31db608cade70eb8e487b1113a46e2b5c7f4a172ad99b502eacdc0f91c295fe608389e61d030607a94d09d349fe1a0cc46d1e07c8db533cedebcb4a3b89afd8b924993\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932", - "725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 34b7f6780620246f5a0a92a768072185f02e57a52db1d865c21c952f4386ddb7e2dc1df076316cb4f2f394397cbcde1af0197fcf33e6428e6f5d42a9ccf623f75fae5940873097d4591d9b1a4cbd00074d134272700ab06d901742da695c3ca9d4f917a808113336f883e769fa8051cdcb0cad7cabd1cc\n\nQuotient = -12b4e74d76bd306d9\nRemainder = 8768fbe8ddbf60b548938d8b4a74c4a326ef335257e5f513e65a7d2cfbe9d456425ceb719407bde3cbc74c9c978970597b5663a0ec61962e77eb351adaee2d2d37f1fb55b5d2ceccf282ea3a0d398be1dd1b166d55dce04a39ef434fa392893618003adcfa61401276ce4e599051ad93152e3477ff524f0c\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c898a753745f0fc178227a7004d917557cf3dcae2e85e95aee51e137b29c895755853ce2d61f214b80070174cad8ebc2795a7d070790acd335b383f9dc88c01227eeab85f1f29d76c1136ffcc7b9fdc073a3a03d8812c7c561b32d8e69754fff64acfd64994b7e9574d2a7cae6bfd5a6fd61dee7ee993bb7\n\nQuotient = -548c97fd02eca7\nRemainder = -939e90e281f97a433eb1c6510668d0fc448f03d737d92693b6362c692167add7e4442105d60ff3db29c03ed06c3121aa4a53c4625906519a4092e4821c918d2264ed0cf088b7da43a222877f3ad9a9fe8ec06fc66b9cfbb44e0fdca1dbe4e461dda9b85231b5b9733e0c78852da83bae557755de3680ab61d4\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2c61dce04200e725ab0ecc5016f66044218391bdf650bc0bd31f3749ac06c24707e79526ee459ccfd4bc22834f8d23f391f2e99135f92b5abd0b04079ab75a263c0e98e46edfb440cd865269ed7872e8c1ada312df1bfd6a5fcd2ebf548d7b7d1d75bc36f62e5e9d15262bb8652a8041e5c8f4d673eecb777d1\n\nQuotient = 14622572f311\nRemainder = -6d197a84d2ed486327790059adb5c073218c56345f48c15caf6892734fff0aa7af4782738bebf24d984bc8adb3056f67e57f9960001a67fa462afd8c57ac9d60ae6517d58ffb4773b637ebe6bf2473a5490511fcdc576a4c40ed03b3afcb2fd27c57b66a26f6d3f9b2bb101502b1117ba3ce7214c9db6302fe20b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b818674faf69bc92085b7230d9335d7bead0413f2905539a54e8d1233843ef13f07cb5538e0787097cb24f152cf54a92e62ef143e31cfbbaf3c09650b14229a4f61a783eead26430949c88a87f1618788abab9728aa52dd8419f5d568e6a109f278b2afdea91cdedca43e562d4bb8fb7f1b7aef13992fa7edc320\n\nQuotient = 5cdbb03ee\nRemainder = 1cfa68d5da7a600a7ac598b9ca1a0759f972fd9a46ba62e5e96d8f6f00fbccd0ab26ca03d14470b43793411ea9803c9409908625fd74ef8f9b2d7c2064b2e3439adcb684e6f01432a1feb0f492fcdd2b8b5a6cdbd0bf460272218bcf763974be8784e5306c219ee535baf5541b8580952e3690b585fd99f77c46d69f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2869338cd16322409d3efbd328b27e2ba53cbf71816ff5c093849b1d866b8cdecbd6bd8ffea0b7787251acb760f85c277ded21e56acef05d29bc728cf44f55be87cb4c8913408a01a1ad53461058a1cf94538f05ec14a6d3eba804264df957de7eb1a61b794a1141218966463dd42402c260c229241ec46afdb5a06a\n\nQuotient = -f16da1\nRemainder = d8b66b622b5a54963c2c84aa186bfde5b67a3562e07a23a5f6843bdb615a3c5d4f007ad8b275ad7e4c5b1436252efe35699cff2e0546e6dd8c7230d6ad560c51cd54db6d312be32ae4c708e9047c3a25c211e2566c58d6b9291de31612006d4e847c6916702be99b3f7ce40e1ac842908acb7f03dc120aa8998c60737\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f8af8fb7002a9d2218dcd0f0c139b8e3dbbd48e25a5c910f6d0b6684bca224f62768b64955580306bac6bfd45b99ad77483563fc7dbe015edc06bee3ff93b0afa8f5866c23c7a7570b366550490c97ad84062c2495cff30717aaa965a8e15e270b504dbd4fa943be4f97a7fd1f3b589bc9fcf4f907a7690d99c978a374\n\nQuotient = -71bc\nRemainder = -13316e9b053a06520526f579718c326402d2a9686d51a340375cb53d7cebba99c8d1ae93388db0a41cf55d5753dd1174014ff3305fcdbd5b02de9e90c45ec0d2900ebf6ef847c2a045eab7f80f07f01c81b9fff093a779a280ae42239df79de8d2ec4bff6723788c86786fe276ae6a4dc1472442b552258e1e5b597305187\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 20fe256859a2e4c4f77db6adef78b2aa4758b29ad0787ce7e277bc68391d5949bb4dd07a9b1a79fe890c8a760871d81adfd3858e27d1bd6de33fd31b8aa6131fef9130a50f995c3be1d615d1bfb9878804b7f6494237d8ad78ac219488f17335ae54b494532f03a3fc8e9576cab6facd90c662658878fec86db66bacda3a7\n\nQuotient = 10\nRemainder = -23e09736f469c83f280052ff01071b1bdb52b7e2b061e8a1a8c6a4e091fcd7ca0b33ade885d928a11a3375599aedfe554d1c2289795daba08f07327a19a8adfc219592bcdf9fc5aee5961a48b3b1b5fc380eff5ed2ba7d7e564462397fb6c6187254ee41c74602b141d7adba99205d2e0b35da57efa96397b3a5d112751cf7b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e849bc0bfd9560cb90e42c8e4e88df175133c14466e530716d89ad0326b660b0e617b4efe8df6b000f517d3cc24d9dd4cafa2773dafd4c6bace0aba54e43c17e8e3ff9497a97ed83e6408aa0aee0e6485dd1d89d52520d1acf4d587422b0c5cd2d5e7e81fdcf842d6331779e800f96628206e8be020ad4021789008a641f67b\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22004040a65f9b6f120bb7243c638cf3a4cf6fc58c230da932c79568f68e31af7a7b8569aae77af671f8335ae68d6dc1698baa9d6ba9cd633a662101b45bde51d55098b50fabde8546f317ecc2ae7a39521bc075942e3751a349f51ca3c371f3b8a6cbbea3e11a334d677c07612bcdca767194c07fca78ea8a06cc3b0dc6dcb8ba\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cad46f410062dc33ad4d712c3b743ae2b7613576b2bd7c346a8479ed679a08e3644c7ee4f23b95f1cc9111905714b170abc37ee1003956f64f0a7e876b38d524fbb2436ed56069479d8d2e4029770f7801a7278fff99b3dc76280f35c7d43ee594073f725554a92eaf4f785c18a7cf6669dce5adb0995233241f3294cfb5bd8f4741\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2fef69f9745646aa13e0c38d77951161a1f881a7ceef", - "032698da3fce00764959f11140bec7d7f53d6777c3622453d4525fb068da48047609d18d463a8fbacde1d21035963b668ca11d5b9ae66db13de7a7a5b66a40608dfb56d9f9f0c8880426641083a05b5ff9e6ba0d6da3a04af1af01dc218e9b4f6ad7b1d3a4d1d26a5c906093b2c\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c50a24e5ddafb768f64677233c5cf09da1b4f06894bd68e194b23feb5c5d6844320a12a02d13ad012f13b1438eedd6313bac9c1f9bb4548fcd314988d8fe0ce6458306735307afe08a96a0c2bcd9cf126f529e48b7ff4b8266caa28c40b5c3d2a473ab8805c860d27d7ee9c032423148d96fad019490ea019d40679de7a2a3323e80979f9\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3a8682d0e5a4efa985dfa8bbddc2c0d72a4400b8b070a8cf7450aa8f831d8a91c9ae3542641b7a4ad793e232a0d301b82664fe2c7f20bd9bf8275828a2a20027d6056b211638b9b0220fa4252d058bb485dd3c4622b1eac97d54b9634b558ff1bd5bd11085d4f3d288f7965af52beaa922b23ac0207d5763c24c085076128e0ef7370eeaa19d\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f00fb238bc9383079c7ecad9b9f6efc622d58a76f2d5d40ec7cd7c3c083c459fbcf3d128df4d20ead5f585505515aab11c36584ca622d28e0cf037419a649d598346063a07e29c61b7a8e76d1949dbce3720d45576763aa0d391b39dd6b694c7cc60a1b4f4f107d87130402985695e1847e82cce39b8d0fb5c88bcf3b37d6dbb90baf5a8553c3a\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b809f6baacecf61198856d9edbb768ca2df2abe9b7b8ce1669fd9259732c8569c0cafde2e32d253094480ed281a8db230f84e780c6e8bbf3657c0b0baaf19ea973fd8daa2870c9d79f3695d78e063f9130fe07ce806a088ca267fd2820f10dac34b5b32aebec20e4362dce26eee0c29d2fedc1e020d452bc2499234d07a2a6e54314e3fd6dd85fe5\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -90ed75629073df816ec1d6dfedd1cdbed9239661e362db706288dc4d774d806bfacfd4b32c3013ec67d8c2af133b46989f12f809fe202d33d5ba53659bd2a9a85d3fa542de4a5c656aacbbf8899aa66ba816b809f2629f37b0444cd3a6dfc99103bcf2a5ee87790b8401be806b5d7fb7064ff0a6fc8ec769d0ccbddbc3d35f7dc4d388d8d28021c95b6\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3f60052c9dfe0bac797a674ca7f11377a24c28a1396ffa0f46acab7909543086aee1995cf51852ea4a21ff4bbf6e7309cba9848a7b2e3b33dbe660bdc58d513d16bc709f1f2253648b46daa7aa037332552db1da81b4ab9850ac4ec66621648fc856a71eee3cedc6617071600ecbc5ac8636233f288ec249b7ae0bac942a5fd539d03990c4fb28a46653aa\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c12fc156d9345cdfcff94bdd324429530ad8caf8afaaa1a82297eb3a8aecf2ac021384036749e489fae05e8776da0deca7e4325436bc8f383bed579c2d67a456c4e23871489780d760d63d0bc0d1d0ab41f06a091b44f602bcdc0bd4e817202e39ca6a934c0c9405adb5a14d24da895c58a81d1c7ce52734183e00d80a414ddd8869998822364e029b3f42cc\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 205dc6227dbd3adf8ee49dffd43f835882822b1c94f92cf38f5efc62f943075d80b33588973a0e0a8ff5e800ede21d394736ba98d4eedc53a9122f8c262cd09fe9e91cedfd0237003b0124d757797ee13cd03e7a3a257bd8df756940a4d22face9287edca00ca23e7d5e629966ef710b07e54241dbace041aa6d9f82687c3ecba818203adb376ec0b201894a500\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -82c30a9ef6a83d81b77825c71ddc563939b8508f1b7e44c725ae0f61006646ba9b86507ec9a4dfd3755ecd8bfb451c2d43a61599732b8aaeedff7a304ce0a9327e2333f75e9a010556ecbc3abaed02214f25e1c8373bfafc2c288ea36b8d5f848b76295a141d8f633609a6656c07f3d98177f5fa83833476dcd111aad179001f81d6013ca3a54cddcd8dc0ce7eb24\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71", - "372b\nB = 33aeafda3cfc20710f0b4a3d9ace4817eed80ca57ce6c82dc2e7946058a40983c9204ac95a1399fa633bc96cb10af3ddeee3ad2337c64391a42dc7794fca629e3e1e4e03a2ae24a000e7113b91c1b6230cce9592e45b6ee7984680b45aa0aabd7f56cab1a64ec310cefe5211821a75deef2e0c8e43eb467dea79dc8c03d2d523734498d079d5493c904a2ebfd8a3a9bd\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b897bc87a40211ef8f93645b1f6c981fa00ab3b12e117a89375400ab5f4c64bfbba01d265c7bc6f5e3a8e26de5de9df3b8f70f4a39c0eba577db5e4b7a68f751b4a69ff4a38915983cbf70dd7e066779405d572f5bbe0719c978b6865ea1a72d90d3ec8a8c146f20d98595036b3de88a7500d7b476644913e4b63e85c4e2632048e9600d553e560759770a902cca680b17\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 20604e080549e1c503049ebf4a56cf9447d90fe699a9773915b0a65588890e15bd58f55ad7b52bd7b7992a8b24704f1dfd5fd07c70aae4ccba5646405ff8a9cbf542dc334cc0c27a790c05420b552539fbf0a155861bec0e4d9e3fbf045720ea3aed58307d5738b64252a963f3fd5ecd0587cb4d7e159b4980dcb112e26c9c34f10a192e090ade157eac1d7a6f970871eaa69\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f11fc9682601cab97c25533b2599f50edb1ac65d46f1969bd9c3cb3717461627621c8cd401a0a0b91f3645b8804e095aecab31c1bab0c26df556adafdd7e7f4f0510e0bceefa3619e26b8c9a1bc613db03857f53e9eb5d4b8f75a8cd1429feb81edc705e5a779d5f95373d2243368ce17ef22da79a6a2672496bdf629171b7973fc4659c8eae9ae867cf38d6d7617029bf59d2e\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3cb0ffbd9ad21d0e86e4e4dab4d237e2a17d97356bdd305fda772fdd99acefcfb8309d813643c852f66e1c6c7fa41ffd44f8335ef7333b2b3e846139fa9be2c4ea762afba4e11263c0b5fab18c5efff2a18d83ee89844f5f4db2c1325f0f55e066a9e01030c07a85e2c9bbd37b5e767ebcc9b95f474ecff24df9ae52a19edeb66546a3a28980f616eb5a351cd399e5f8436f17faf6\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b8aaffe779855c6ae51807f8cba780aa64bc22e8fa5e33f7f1dcb084fc476791565bc33eb37b4f791ef5cf46d64576f48b5fadc9f096f20c798355861ce5d24a7be1450bb871f9821099f98213d74a5e5cf83b895ae65e0e0fd096698463906a112e6e169a1cc0769df7a5ba6812300fdd33611761b6339385e1a70f8f8b2be7679ca216f5b183140e69586a27aaa9f2fac118118875\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b7ee3ee34347dd89ba4a81415aa1269d0390346597b07444f0febb71d490a01b6fee174634bd88e8aa180409549b2726d044b4690353de2fb2294c8f69c612485aa066f68fdb89466760a85901cbc7312bfe5a6f656e67dfd2d4ee099ff97694b01d6d5b8626ab1650eac5267be53f5f3ced5dda1aa86bf42ae132a28fddb94902a515da40e0fd0586dc8b17a34af8eb03d06f70ab89df\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -bf8213944ba785e01b8d37a12de77b2ce1492f34bf6f67406cb51da89675b4f70f4d4f314f30ca8d65cbc48ee2fa1f0a3e4ac0de3a87d2c4c589b6812e850623d78ef2e46fbb555f6d3c69b211892c11a4a2dc3d8a9a19e96a07952602ed5ffc0232c140c3e828acf990e5425d8dd9ce0c1107ad1c6f96c8fbc90ffa457abab0d843094dca3c8a45ddad81b7850190625613a4851485f38fd\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3083421e375f0722b9397e156de47f77635d62ba1d51794469371b473b71c02e3722841bca2ca06b5d1cf1492bbacfa0abfe394dfdaa7bb8787550ddbd953540e9c97631d9a1efe0c8f8e14f395c82d20245cec6d8021f8564b4d66e7779c3245734c56fb74481172f4e349d9a113cd0ee5263c69ebf746c5285cd4c0fa91d9531f769fea3610c2972ccfe9a22c00aa62ebf52b3a4c6135f3069\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d736bce537f47ae4797faad797af8cfeaf8a4fd42df1f7e61febf8ebf6e47dabc48252ff7948f3dbf8cc369b6952dc58f64cf09b4c53447d135c7a753c21b6052a9726a47a61e13628edf0f2bdb357f2e780ac1ae1f28f211296c8961c2955b773d7dc2904dfea96780b2877af133c9591a0dd54cb20884f014f363862478ee7ec45236bfdcf0321af0692e68f744af28fbcca827ebdc7b210da38\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774", - "ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2cf1708f1e675ba688c0d19eb61a05d2c8642528ea6b1512375faa732acc59ec04ea0aa55e0049144be09eae1292b6cba6db7a9823f1e912df6a5032bb9674f4f26c0c8244ea0dde7acfda566574956cdc33e4a27bcdea25fe255c19f218cc4316ae8428ea61d1bf865197a066b959c5fcbd7c9596207997d05fc38e32322aa189ea06cf5139522571661745c0d72b740dc6d842f1dd8481e318b5792\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -a9180e44a284b5bbe72fff46e55869f749b626ac33c8cb17be1fc260d7c6f460f24a89e1367112e00d0da4d213a821d09f103f35bc4eade5605bef23c5d048b1cfb45dace8b9c637af626a85fc773cf51e6602a7a5999a030030cf114ed6a4ed7583465b9303a72e7f60824c12329517c6763b0f64abd8ba2b9b26cebe882a51f05ef8076e527d53a213db910a5f42be5fb78729a3dcd08d69a709920a2\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f26e156b3b1117f7cec542b20fcc06ca66cec03a19b6f5eeebf22b4c0fc265df5ff06fc9dcac569735135bdc142b526b295225711efb71577b10aacda2fa446f5208487c725407c2188b3185237740c813e4455a6f1dde4f62916237f23164a3471aac0fcfe24ad1ce1dd81a6144f5861ad0cf22dc337abe10fc4a88b36116dc4929602ab48eb971fdd7a5ff747d6b9e0b2bff75c59621550991966a0a19f\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9fe18ae697576dd36ebdb621d14cac1cfdfd1f5cbb7cfa8962c5a7dace96f9f54fb4f4cf2e650dbec5d1ba89ba53d251ecef7dcc1cab8c2ff3d77903f5fb5f29a4e8e3a2a3c05c105d5733b5132f2f8d88f99d17de86ca1191c32ad8ed469bb649ef188306f69f183bd0fcc32759e4f855170f88c0a3f6745aa98f6225536821bfa056a42b37535a622f42b009859c974cabf2e14f75c749d0fe5a01fb3ab0c0\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33ab185854b20a8126884eed85181b14e75d4ee452958cc1043b099bc16c24b9c2f3e0b792744f230013907844496e600389800e45fd55133fff0cf19c9c152b9d031039eb90da568f9c5212a3ba283f4d1353ff8ff9dd04d292c265bdcb77c3e411716f471930bccbb8ddb819ebb0e0036dc1a18457cd97f4f5909a725baabbd15e8ce33875895aa8dce77a4dbedeb0271a2a4a17f77f5920c3776caa4a75ac650\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e7ca0c037bf8bad5f8d9c5a2737e044d9f7284c616156d142612a53eb217f57f4aa00b6daa424e6c0d9163939e1ad0510a1cd64fbd576f3e54c59d7aa6228fb3caaba7cdcc951e00ed141ac3a68abb9780bf46bf544fe0e347f677288e962fb69782741df49b27cbbe8720c6f8f2e769147d89df6e17e3c592bede2e696d384b9f01b99b31c505d67eb6193a8844f8c4cdadc9fe45dd446a0dc572c9da6e58ed303f2\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22b76d6973e37aff4a09216e57662f186c0a0748c4375d6bed370ea61d1f6fac2d9bbe04487a629118b6b0b0c8cc4179fff7bedcf048cc529498bbd9cc81ef3a103d6cac49d58bc41c83f961b6df7f00c7171fb7d9359e03c76e4364cffae5f67321ce646e9b05f9c04aa16ea65389e940022eda6dc740ddc070bfc7e589b86fd1559dc320701c39de20d54d0483fdeef6c4fd012850630b982c2e243ac1ff918377ceb4\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e6e4d69a82b83e26ef8ac0f4c3a211153ea6655b7ca12840e7b866510d114693049c5b8b22c3a097eac832bbd1986e60564298e54dba3316807ad64bd6c18903a0f22660c9e8d5dac180f57cbb90b176b842d5b58d6dd9f47499a037833a92a18f397238a8bcdc4afd129382fd6d200d3d267ca1e6bcc2cc65950831cb8e30bcc01665c8149b874c9f11168153c187341afdc43e4d8652ce4fbed9f9eac75db40d64344ade\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 319a81f052db21ee213c536db2cb8a71e0dcd0a9b2ce780a9588c38b717c5e487a337f82b5223f638fb552e92b826192e6a1c27771d1e86584bc6c7cbc5d9a6ce6edf2ea2ccf6939485959ccbf3183b40e410768c4665adf90a0ae2792fb4b5d8aaa06c6294e31893620decc3bc72fb4eb68f1e56b48e39c59abe869d07509b7564268d0b7f178ef09ef5dcde6e7dbd2a20fd1d4fcd707943dd63adf590a117ead1ad10ff85cb\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -eced809145e696ceaa0", - "ee8f831eca67049509b31a1b15e7fc86cdd97a73a2ca05bfea5f4b283d287e49906463ef36f2f8ea23c2aa12d5534c08e9769055e04822be0f8ac85f404f5c025a6833b4115f78da9470451c852ba0f24062397d20385f58c5aca10f3f09072b2592e5672ffb989a390abf86cbce74268aef1f4ffde730b3b962df1088bf8745105a7462379ce142f819c2538d9bba99e094ffbc4478625bc54df16c5e1a\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2c1ffbbb30e71d5fa77b5473392f95297b489c85f83013262abbe948842473154e00c86b2e354278844083f960fd746a3b7cb9baecb9c66932774b3a28f678d50dd8fe52fbeead43d8c8adad7c0fcdbe5e02664b0feb0ce214c5fa007c5fa2d08c5fe96787b95639311cc4b7eb2a7217c9c38c6d93444fa60c1f52ddae9bb2ec1a49a593e210e47377d3623cd2c4994ad9343863443911062e12233176f4a65ec715b3c9731c4a0cec\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c3bf056b905c0392a7b5fa57446ed350f325eb67d59f1784c744b04c7f4d8f5397db913407aa8a7f1dd0225c1a9673828db0d8bf3d4908ef53307131bf5b5c4c6068ad73b874aab98e8db33b0a758532172acd8b2c830d0679a8226537090166317b8eea91e8ee4a7282c0ab0ab6f2b7b63d728d22b534fdc88294c376a8d036ba9a644c2489bcc84f6aec83afbac08067a7b93f3897f8dadfb68c327b751841927a728faba47dc44ec4\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 23fcf9510caa531a304eee8d0b2d49050fca83abbf287b6b6dea06501c5afc6d87d2924df1d45b1bf6c4bf77b563a3013cfb4ad9094f8ee9892d33f6ee1c70131cd5721c5af804a9da7654510e8591aa185ee723f8caa78046d9e6fbb891e6024d2ec70110ae61c3969995e35941d2c7f3779d5bb71ce5b693bc9ce4b087068adbb554acc4ab23624e060f7cea169ab512a06ff3d2a36c2b6e3bd9a75f1a9ad30a6a16b0256c42eaff2c3f4\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c32d5e643b12db6616554116299c1da672efff1eee394378c5e9e5f702ea4ad64f0dac8904bd2751d2cef91adcb283599f6c661967dbab27059e94dd50025489cf74c6897a22e95013669aa3063fcdd4b73aa6a9a1ba5cad3956bb26346e22df6741cd0ba1c0ab87fbe74035618a394383823216df47b910cae495b8fe7ac5feb3b2cf0d0ef6c75db477160b75324db8eeac48a0fce72b9abbd7079ce6f529a89025a03a3777cc7d1deaf3e4a\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2a8f2c530342bb6ce683a760540e956a1155c0fe065476e400caec59861ca97ca71e51a11b3213b2baea1a41a29449998778e0f533fcc181698d293f05e28bff2750ef4095170de98a19a36ddcf59a65f3789a3808ead51680245070262c9544e446f23652eba47065a2bc4701c55378bd49733619ed2c213f8ed12a4a317c465f37efe07ff2df8e88fc33d3eb42cde9408dda28215702bfa607030839285a8bbf89b5e8842fa7d7f50d83fd4ab5\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -bcd2b2362aa146cd120b729e81c98ae598804006d046a7ed0f9782baa10a85e37c7c22288dc61c24830a1b42b123d63779e88d7555028292fed5ada1793264b35e961b608bdd7398e421c5474c33a65059ef13787e0cedf4f8f032beac48c4b5e5a67417109142a43b198ab617d1de1a38d6fb4922c6ef70a5aad3faf6f8d5da3af9679c94cf61ee760ba792d2972376425e2ec9c4109e969e3d9c3dd90cdbaeaeb7382cb7bd024b75a1fd6d621c13\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3940430ace4b5b87bf4baa2673582db3d27307ca4cd8e55e976ea3e10da72b6deb7de932253bc9228c85cd4ae7766cd0264004c658a66d81e60bb9bf4dd66e2afe11057b7f7b53a1ec222510748be53a93970fb056e8082631b2b77413fccb6e61cdc6f224b7903d75345afed8a4f194b4bcedfee1f16dc256c2bb9f4a129fab6a9fe752895a93937a3d087ab7ca212991ff34f1bf1c55987a574674af43986312bbc3bad3280bbddf4ab0217440f851b\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f0dc20b88450f45381791e85d080e4f2cf38837391e16e608b8cb5e0ac0ca75e9f72cc04bf2f56f130d46aff31efbabc0ab14f0c0ad680d6899797297152be85ac012644c8d0927b5b6c70dc3e5a8d79ef92a0873ec22af3d9683bb5db1ffd5ebfb698c5ea64cbe2b6a8b9f14d4c18624be1b78b19eca14942ae9542012692cd0d5289ebf75fcf5486596f92659143e9f952af3622137e633376fb95e628055e0fb1ba3a37ccdf0af69a4c0d6b0793078e0\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f2135850715f623909e41a745eaf7b37593567fa8be2d1ccf76d10b93a096e244b91d8700cca37a2ec1bff7c3d21cc3211ea8b03a3594921dec32faa185e7f3d9d17e98cbf8d881fd2abb9", - "44181659242ede21df7e5e8784f541cad678df1ef6ca4a5fa91f7856c62fe593c4d24436810cf4fbd11125bcb571f6975d82afeb81bd0c7700e053fc175fb5fc7b329c438479a863b8d5fbe6b4436b67355c51d0306e8847a27a30c9e61f0e08232673cdf0ba4e0\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cf429f101a2e19a65af1e238f6745215cf476ff2609c846f10289f1ef21b89af2aec53def3f4ec07ea42041f8b5862dc37fd03b2df12adaa8c9f1933cc69b526d47797b40f49545fd093b8ceddee3c55721d1fa19b336218de0cac56d410cc6cff4e620578cf820f5cdaadc367dc4d6372aab1e0ae3831a6d153c14920b1dcf09e7629b7442a06385420d79742e409677e3b82ec58bcbfa668ca072e981e20728a983d84a432605389c855a6668e0ee0d2b67449\n\n\n# ModMul tests.\n#\n# These test vectors satisfy A * B = ModMul (mod M) and 0 <= ModMul < M.\n\nModMul = ae2ca2ce7addaee2e2b7752e286b2bb6a58b51cfbed5c924f00398e59ec36fe6341cd83da43a33a12410f45f6228079c4aeb3912be87e2e81fa1799151bfa0fea29873097475b2c3efa312145d0bf7e51b2a7c9bc961a4f4dcf0c883ff90b919b87c21099fba40257645be31f95a3a277\nA = 6b18497fed9befdf22a01d988d34213f6687d8a96e86c188dea4172e7c6095a0d18d3c86c0f5a1af9c6e3aaeb6baac2a510930b3ed06ec78ec2e12b\nB = 1a058d99397db0d209f01212dd4023ae01b15da04fe62d1f76f21622b2695558c67d706c535ca7f19b36f8ef2d508ffd6cf6fcf25e5\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462c7cdd79b7604246a0cd97b40ea5a9a77408f13cbb548b56ee713c690dac0507fd988bf28e77462832f4307b08564a51510d4a951c1ad7564316dbead2b53540090827a8ade8092a6133af0e5fac7310f787dc1472836178ed6992b9f71224da3e884bef8e8379a58e6d4be0fbaf59bc520f786631857213305e23fd5ca65\nA = 16c92f77c139706430f396f72ec7adb045745cd9f5899b0074d9955bd32de66f57c05c7929b575312a7f1c04f19e724d64744bff7b31ad0e6171437763\nB = -8734c4a2361fc530f60b28a5f1c7e93136c5ff6bfc7553965eaca54c61e6befb3c0f8cef4280e780cc5940d21a740debba31f863ded75\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462c7cdd79b76042469eb41a7a83115eb84103da4ba438c3e33227631dc185054ba4e607141d1e60990d8aad4e0bb0ceb645ce9ccdfe72d4738cbe1f6a73ed3e070194fa4feca6001c4a853940a227d15c1f1cc153d8c96e90e24805929fb11e0665e0c41c77d5a97fc5903a8b215360e26f6a19922d650f460f7056274ee92\nA = -6715098ab2ba3ea1e6341e89936e3ae913cdd450dc831c8534071f3c362841e47d88f2cd29c0d1239aa0949f3685f12f8519625bbf10b2c7a515e6d00942\nB = 536d4b3e4815ae5ed55bae6950f5a8a61d52439d2800ef1b5ba2285b85ed0f6ec4af9fa0e364a6b14f6f6b8bebce9200467804e787f9f3e9\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 309b3e30f74c58beca8b2c23f64fe1203830db8a7e306e1fa2e2022f0d6d422851da509d1b2936f088f0e35effe12a7463f47ca369bee2f2980bc48dd8e696b2d8c6f35cf55fb8baafc2e613b4c684de26129cf196741aab873f81e498b1e03018a539b5eadffeb5953029f31f8579df7ec0ff3f752491910\nA = -11fec955948e007b59fc50e729941ee9d43d552b9411510b73f6b4faafc0465f261f8381d96f647267f72175883172918b5c866cf1f1ffc43c55f3c96a60c01\nB = -2b3792f39499767e0a8b7a6a406e470a78f97ebb36765beab5fe52e95abf7582736db72a2ebfdb2405e3954c968b350a459ff84ef815dbc5910\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9143ec3e9f74a8eec476cab17ad8636eaa7c60e108e89ae0702dbdb2b255a217ba2530c6fd52658cd931b962054a9c20c8713976ef3b7989c40611cd25b0a9ad0635d61f6dc95dba6e0c4a7d53ff539b623b97ba3d66344fa324f905abb861c6b1e830c4b0fd5f6a4b01f09c8e1408941291b2285c4625267a108c\nA = 7713413d87f1e50840255927ff27bad79e5de5898725a876e4647913158cda9f5fa031dd7fc11d2e8130a0ba99e8706341c1a98d5fee3218763ceb1d131e9cdcc\nB = 1384e60753dd4bc20cdabf398525e7c4aa40065255c5058cae0b2ec90a3821bea8de672a712431aef5864eab719ba621cbbd8b46fe86fb31286091\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462b3b4a0432890d141c0f46a28190a2e30ebb2e4ba90ed132169cd72316b290dbf5c261984d98e63eea6525fa890bf52185ad7f164cf49f67ca91c2f35511f3bef6eb7f3da31a602a78e4752e326d79dea729f4ca6438f2aa65eff44bc60979b42e44f6a301cb5de8fb42abb47bce5633c6ae9479d39c9e8b507d96161e0fc\nA = 17d806d7c76aa8acb051fd9c0c782443f1b1b6387455f7cfb737c41658d0459bda5d13587055eafb87ad8d209bccac1fdc392aeca0774ea48799511c1fb9141cad2f\nB = -d7c9b6574354e131de4b8643d766641e98554a03238ebfce1112c3da5f049d6c410a7f05758571aa2625f7190b936a214797570539317b32fb94cfd8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 16c84ed15ec6352a8ce6d5c2bdc0d9f13b333072fc7041146e944a29391f83e346b8ac0bee6dde98a420ba4f8852801d7c5bea6f1177a6cbf799edf2146f8297013e0e796917cc967786788ff12d9c1d07d9ce4b897bd22a1b8a391d3b4ecaa5b5c85d0a03aea5145db6350c42a964a41ee5f83e7d35e14cf442e5d99ccd0ac8\nA = -6d84cdf18a2f53fe496248fafef183914d55c42267af3dd42a39515e80cf29211fd58454986f5fb6afb56170dd9865d3158249090270bb9af341c830522a4dcabfd494\nB = 6f6f3f74187b7d74dee92f79be864d0a2c56d4bca3283742e9cdf15112c8f4208e3ac8ecc98b44b4ad74b0671afa4aa9e48dc31d34224a1f66bb2b4658a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8fb782e4883ccf3aaa2d3e020b08993d580c69ec8fe66ecac152c5babc8aeffafe406736cea492450fe6adc25dfa2e12723a3f9baeb02fc0f785b3db760ed28048e1710a78a2ae0c96b67c109c5034375a512b6fc7906847253f66316baa0ef90facc9ab992235153684d49d6939ab9e91086529494d7386f604ed69aca2f53\nA = -1f745c8f0c8fe6ce3f893d77fb274c61b72b2d9f9c5a2eb2467bc00d1f496d0ad469d76bce318bd64ff1107ee5fcad4469f84d658586a5789c068b0cb9b866d8fdcbcac5f\nB = -3a2347b491813252e8ebef1bd181534b074a368d076b8c80bde2e54ec3b4ec99001f43080c7857427e069d99b1b65cff998a141ca6963aa5fad1ee632986ad\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7c0c1c05ae1d6420bd93596a01aa0153000ecce660a8a14d6fde7d4740719cc495fe6681a9a08163b2dfd51659b3ae7db0fbe09504370bfc695457d7b32665a4df53e879ac817bf715d5bd6ca0e242b1ebacb1ffd6698ec90c442910a92b35ec103b345f9a9e5c7b005f8028da4dde80f36f6f6e5675040d19e46aef06040eb3\nA = 4c09264420a9452c6f0b55baee42c076aae5a73697cc6bbb88b7c922f236ee4c18e477f88e2c40cee03f0bbe87d3ac8dffd75f635315f856a3881c6373e8b9a286c813325d3\nB = 10474ece7ddae5c53c4df5b594439124370932dd94aa5d5b4ddaa233b1a55634fb7d72e33bf1b02965fa9d1538f97e1cdb5ec0477cec8ebaf202aff8533211169\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5", - "f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 481543f1556df756ae2e422ffe35aae020c9bde9e9b1f760b43043a4654de363dc67f381c0df1c3c1b90edb4343c47ffb8345a1aaf5dae56f446fee08a0b9ee8c42fff57143e10846610a9925be96418c4c957b4e92af734b96fd6f21974877dba52a0db1fec4aa97640e357434f95ba74b6b8323cbe17118dc489552844602c\nA = 11bccd165d9fa2d8b01a48c0ec549a6e600396cd2023f0240056193ad27e971c604eda8aaed6ff6be8be1001f3dbdc8655f1ae84eceb963938ae7bf428eb5c968f584798c1bd8b\nB = -cfb6629ddfc98a242e3290959f4d0726c0b1770b52393bc7488a471a90f7f0951362c03e67f443c9ecf4987f5303a789bf65e0fd59cc5eeb9f5d4f40d3e4a14080c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2a770ccfbcb2bad207d0e2dfaeed04b6e7509daef00a1df88e57509451739a8a0f15106ce8b53d280a4b4e09900420714cb6961ebb0e00e88567c5df50d2f2908b4bf8e0a9a5a8b3c6120503c14f16a99297459543c467dcb67915e0a10e19f72ed5b6891a6121b66abaa602818801d3306630bb04ea57e6b31b2c05e368d398\nA = -442c80289bfbf00db06eafbf06109b55f99786a323fc2c6db5686f99094cc24aef50475841243ec3ade2a1e0ff28b4032fd8afb8bb5e28f3b2863bdb9fc8f033adbaeb5f2ab16fe9\nB = 6d43e3c46f4a55d49e78f40d34033a7f5fcbe50873930e7c5452b6b3b176534e6e70033868c85b4d63052964093214dfd0bda6a84e893b1aae3cc72aa83d039e51c014\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = ba0e8c91a86af1001b13deb115c77609a1e7a3736a6b807255aee898e3100f469ef6222be532dedb1b8d3db4b3b55aa4b5da5629c83e9b2bde76bf2f2a4119a5378b5cde000980b3e58595d988ff776f0388fe025625ccf368e20914fa90dc771c826e4a836b2890e82ac2274471d586b4de5dab3278f0e70207562ac6e6493b\nA = -14be403d28c8451cac4dc83fbf895a9d2b74f730c39b0fcb33d7258f99211dde31a78f182ad1d27a559031d67d6f2f94a741f141bab80fc692afb452ee2d502099ebd5760ccec7f7ebf\nB = -2742dfd02134594edc6d3025aba5ca4a34dfeb43821ad84164510b43be4fb95748f8d0eed7bbcbeca14efe843fb676882784bb36c889be29bdad9270e0956286552119561\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 20c691d6544912fadfd9894cbfd42745991f39a29cbe3a1cdd302bd0487bf70c0179b9579b77f8481bee13ddbe42f32d734b6118af92884c946ea8576f6dec867c1c251c73777cad7c7c76e90da00ae07f96c8d6a751e5b18157dac4468c05d32eb86e74e0e8312bef85905af8193a3f5c799c5875badbc9eb7ead1258e56d7c\nA = 7ae9b4d5151b11bb7bd4d1569a6f4804f3b4d77948e0c6300e4f28d51c9a0afed2ae7503e53489edca5359e2b3d0c82a9cef316cd7e1c1275c31fc9c51a8c1e5fdf23935484e467d6460d\nB = 1f46f88d39fbedffa8501fa1268bdf3460aa98e12b629da59676e61852a4d3f8c59f72a2fd717fe2faa09639bc651ba516cd39297e0cac67444ec57c0db47c2a4e250033d02c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bf21b3cd55c0df8d4d568d00f757b10ef3de782ae71b289cb2b59d36df1341382bdc1825ba13199f2cf279a72968b3bbf5f7e3d13ea9adeb96d81132788231fd988eef04828119dcca21ec1fe844998909cc95a8d01720e883df27f07ef4dc3f09081015dbbdf019b96707c18b0b1db6e689e8f86466a2afea4a9cafc576e10c\nA = 1243b14aa3d16a55935f6f8ca49295e35e7f75b03de7192e1e8a479abc0a430e0d340acc05eb9a61a5dcbfe3ce3a4c5c940699f5043e924f282bd21e341edf8b7a6741c6ac72d7587a9e7a60\nB = -bcf08b2153e8ca911096189e35dbdb21b77ce89685484f574c89f1747612f39340bf1b204a23530abb36b2c5e195940b86ef1252d6729393c25d4c73dd434b6dbc3057b05d3f15\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 460539d96c07e72acba5b59c88fe904bf7f1e1648612908444b0b08172d05968b31b43456918b4287dbe01afc3cb4860d9c2fe549a580c989b6507094f6c241eadff910d2603f747f8e289e7a8176ca4a978bba89288a4cf875bf3e03939af966c54e77c28119a39d34a2b7055465f58ef2efe7c82ac547fb675653198e4b504\nA = -5a44cb669c055ba7c28d49f84bf8d12179aa30bbb9db2a48d7a6b09e44dc0e0f7471e3629cd2fb51e5a53346ae025fb49f9591ed1d71bc79daeb3f1254342d8a2b091ae07a758c1555efe59e78\nB = 646cc0f766346aaecbc5147a4488ce157a6d844045b80884eaee9d419087285fa71108b5ab4a05689aacc8d2e3dd0e6714c55eb8f77487a3fc5e56c3c2df0c4acf28a457051118560\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 79b536f4f30f9f7483f90e65e6456ef8072d9a7430405cf8c9377ceea2c676afc338837643436d55ac6af2326ebb362684bccc5092367209822581700d641cb8d331432b761e4c6e22639a27335f45a25ec019d180fc53dfb53d69216d7cfaeaa07db8288adc35b7bbccf2829631c1eebb821e4d3299015c3d462dc17aee5024\nA = -167529b1e8668938ec02a68bf4d76c22dd018c41e19be25e2f821f63c2046085d0af30d8b4212ea0f3f9943be1c14fb2d2a944551107cd2bbf8dda5bf258957325f06277036282977db4575b0deaa\nB = -378e1be10a57e03b197bc2b1287d643ba6d89da4bf6a6170816691fb6529c602eced237863ee39659be3729825f032a57eb5de0a87b0894d1a1244523e85b6f50a3d9976dbb038490e46\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 658169197ddd0bfae101c10c3e6a2b10dbb456048e81160b47b197fef439b1e0ed710399cfc80ead8e436f1c0399064f92da50afc335847515686e055fc7bcc0ca721184435955b896b0af4f4d96672ebed2f154538d49fa507b945c0a6ae926793751231980274213c80046666c28ada213a2f87509d1466b8d1b2122e93f8\nA = 49136d37ae8f3da71a6114327833e8aaf3dc8b5a9a27e9d04c953988456e525263f86ba94397321c2093803b789f8db3ed7cdba19c4b796500b979e02952e1625246f8e977e01fccc133f94cb22832c\nB = 1dca005663385fc00b4fd58c73adc7589d15ddbcb8cb2fba03a737a320c447a2b21e576ceda73811a31d8277883fd31e22f776bff3261a098ecf8f40f2855b0c723d1265eeafb43f85323e3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a49fc8084f3e780537b4038bb769b8db3653a3315298a99c2ede6739a1732a636e9787f2e8b09d0b9bea08fac43cccca71a315e6f4a7d6417d171b4693dbdbee8cd9f95be0847ffd40ff027267125d67b89737e1d0365bef6c4429504d13cd8ddc7810f456d6293c0c57c14a307b94010d79d5c13b92a907f923966fd3c5c8ea\nA = 1e7d8de2061cca59d1cc19b356a8fcdf2ccf917e0d81598f014167c5a8de027ccfc8f2cb8c37c396ebaac83ba862c146bb2d551d10ce03de9528f97725804e8a6de57b9d9da811200604c2a032462b6ac1\nB = -e38592f3acd75b575f64ced439d5ef2377d21c61bc70625639b01bf755fa2c6de803ce155744993493debcd4de40860bbfcee86d0b117d7f8c3f8ace68b67cb6fe7a81a145535553896424f7a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5a99c8a6afaa97d8e7d84f4899803c7786b1bfd2ecabdbfbb3bbb92247ff91ac213a72f6d23c24699d60babe91a7d9cea751e686c027fa1c954474fa5680f0059118426c71299462b11de5f2817d190599cc4b352df4d2e80605f9ad1e32eb13712d3027a2b6a19d52151e37e7fa057d8fe59dfc8a943a42a1756a38f103a75c\nA = -7df29221e6a102e32757c18f87927cdc90ecb012ab0557e0ab855daba832d76ddf595b9c5a62988ca968b64fd5bba2a147a5991810c17cae7edfde38bdbb7e13a1fe5206724c05a9fc9276c8d4e503a860c7\nB = 5c586d1aff7dafea3b8ee42e0e8854712c95385374b5bd1fc8ec41a72b296e070940c4160509a4a1699a678533ff3d12299338fc441b0f01e29a48677bfc5aebc644555285756e97c74e1af6aaa8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ec", - "fa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 21fd2d881b6a52332dceea42664aeae1ca110512c13bb33e25ba4ec0f39f80eb73b1fa0834c998c23a2453dbff971eadb183c51a30ba78d593f23be9cb6b2b33a554ef31e4a36e0314fc2ec889f18debb956b89d1bf8172553271bd56d89ed0b30abb70e68abaa2c76f73cd5a3de93433747d09c845b5f8843f9fdf9f6c975c8\nA = -19fe3bdddcf08190a037768b77666de803ca4f7f0d7dbe6aaaf334a486dd0da7ca024d1b3df11e0406b0326595a171be30b04574c1a7d04f4d2ccd334663690fd20e4fd168386280510a00a70c1a11e99483048\nB = -33b2400173c057980b0e0cfabbda1a5cb5b83b7ae80708c199f28142237f04b071c6eeb63d42e80eec04b76152250c9e4d4c4f19a048cb9815dce6e66710fad1d27494db5c31d9af37d2aa779d12d7f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1c45cfacf30682a876cfe253f05b393a2cd4dc065ce73126508ce897a99a723cf5145187643ee62d746f6edf70269ddce3c348a1432316286a648ee9ac31ef87feb14f25c42f2dfc2e84bb5bdb4ec0124e249c526c55ff2cd0ae938555c5f86d856eb181572ed01dc045f1ababa52d249e56aba0ecccda905d7d1e64bf89bfe8\nA = 6a40d948eac2fe5bf6db15d7f6b89fdc0712e32d39a881c21859e8f7722391ce05973efc7c40e2c0d7f56c217d8a986bfdb08bf87bc0435873cfe4d01967c46f7d39464bec411d0369f6f5d1d83f42596fa47451d\nB = 12529775e8253ba220d890d4912fb95f91e4edb59610e889431208b6bb42b089cf2aaa12ff9ff98c2482e7f4cbf35b22d15fa28aa288217bf766e937a706fe1e600143087b0a67f668cb7b762c9b9f38c0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3b3b08e8eda8be3918bf648227eb0d569dd898729d9cd54deb32b1a1dc69cf7b2c4184c8ae9641f0f75950df263a5e236f428ca86244e617b14a04edd0f31c02bd4d84f25bacfcd4a2786825f0361251475eb6c7e99020dfee4298a1f1bc260d4e364a332bc6f651dde7ce5026dbeb0e5aa75ee98874da54c7930108ad28e3a0\nA = 149d36918fffa682cf90c4d3f3d48e6408e7ddcbeb44e78b9cc7fbb08108f65215761a61d79f37ec8f67cc51e0a9b4bcb3834b0ebcf6734985153f29a2778473b80147eddc813b4fbeb98843f5c1ae6cea68f88dbb4c\nB = -ca87f66182e271a69c0964eda92a009d438078b584c3eede28ce1a501838c5f497186d305c09922f32ba858fb55f2a0dbfc9cd0f93b789c1f800cf092726d6d33db19e4f26c7dfca69b83925db14544ebfe2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b199655160d88b6b4157ada0e5675f82b33b5592408bb57c46e2f7d8791bfccaa51436dc3b772b83e907c20ce7edc2835ce96595b78c0647d244e9bad6f4184e0003eb0899e7a47ba0be888b9bf795eba95e5073a85c4d20416fcd4a8d4e1e16b403deb38845fb8bf9e9264d68807acf02d579e8cd104cf2bd555e6cf73d0450\nA = -70ccbb73e33a7cec30ef2071f3b1f2e008e70fd6d00fe8b7aa4b9146fc6d0549c57d984cd014c7e0a4ed6d33376998b7c2c9778fb9580d8ca4ba795c88612721c153c186740c58df3fa63b6cf7a4de76e049217218c05c\nB = 6cf4168d44a8da8e8446b4420466fefbdeeaf9623a40e10b77547687b25f36916f2c18cf6060c03b3b40e0959479f6aad5e44dcff0ba799262ef53e280f4a7f667d262d472b2e573265774deb5ff8f25dc1822b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6ff91af444c61d2e2fe8ad73bdc5377d5becd55074eb60f0f98eca3d8f4be8c02f196b3afea12c36f78b78ae6a5ab677ffb7d9c0bd58987cca816affe468c7fb4b56055f5d2326532d6ed1c00ca2d052ecd103994e8929bce04e067082b4ded7e1973566f99c514b4e0d95b9a8a931ef4f6355066940990fead70208a63841f8\nA = -1c924bea12ad6f8b65abd1796e381fee2cfbec15138191bc22d57165928794bb080c83878fa5fd19a5d657b2fa91165459966f50aabf19440f7d75f027b32e999ff4d3f7a7ce878fe0f33a847d644d86ca19713ca9968d97c\nB = -3abd4b281b8f25f5957d1f2fde904457d49a3a7eeceada26b454ceb4ae0e879135d376571f08b5038b7b3d73a9a9fecbe265b72375756a715a523ba66737085e5ef7a4ad988155adc93eadd5d95a0faea56914983b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b9076229b1a1241e8b4da3fe143ac31d060785be6ac1e841c2fa9683d2bacff2e2b5dbac33f58b0b1718ad2053c37ee55ea54a9d258ddd8930d2784852844d85db24e4721762839a5c73cfe588efedc8932ccfa585e1b5975083919be9e32a86dbdf5cef84d3d4b2ccaf7a006c0cadca1e35fff2da9da7d7e779494d8f85bf4c\nA = 75eb0fe6c07559c2b0c7b2acd7d29b5798f6c4cda64a504ebabdf54bdc773ab28b218f0defc040016178958d5561796230b71edf49bbdcbd3f14494859843c8ca7a0f777cb05827f2839f3982832f4f3e3c5e50af17ecebbbc3\nB = 1b8aa718d61447003fdbaa748a9d86befdd2675a677cf34a1be7c81e4577f665d71135a8a243976a4f6ffa1636695567bde522f8fb1948033a7e0941f833d827e957781cb4349a08c6be418befc8959960fd5fc1b288c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9df82b7c34ca97a3a5d4efa28d5ed4f35484914dd73af9090c4bb31ea3496ece8ec650f4e7b07dc779c97e597e76e43cdadbfc6e72b61ea718c073be1cd204f8ad2bad0df1e530e75705f3d3dc285e9d793c8d42f04dc20773d3fcda8ef3ac1cb10d33d20a91add0358ab8658f49d2fe51d0d2d72684e31c0eef85e5695bb4b4\nA = 1fc2a171445ee6add5c2e4d29e50b91d83338f8d63c111e4d3e95f16d2a33be02bef24dcc3d6ce6bb8f1ef980dbf8fed409a0232c0566153014eef840aff58ed8c33e8d463d408f93e2f5381a26fdea63676c4e5397eba1d39f928\nB = -bdac7a177c77451104852bb99004ce8e617036906667258d85adcbe8cda21ab7d03aa7dcf62cb210a9db8fc750c7e1ad290b35473be0fd607fcdc686de0b78fd9f258f5b25e2ed43c2ad1a38859f882b9f6b293dc258659\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bd9f3d2e8a1086b177698f87a9860e3a5f030e04a0bf4ee9436ac55e005bda01ff4ac662cb85d39e98a41c723ae542a83a936c3bd0280c6801ffda080ec0aa4230b45dcd0bc5eb41cfcf272028bce3572847637a92d1543bb2b8408e880f5b776e1cf14fa28d15cfb584f025596ff10c9f091c837a3aa622d9e5c856db8ac207\nA = -7fd5357cbee7c5e31fb62ad03bd47b705b574d915200fc7f1013d836b9cb683db020b152ae9464de6aeb8baf14999ac7025dde6173fae6ade325c60ec310eff6dc4130a8efffb15ddae90d760cb7f76a27d0368175d4a44a22f7f223\nB = 5894a0223e4aafe4efd4572752fbde4952c8b09cdfc35137e7e6ed650f8fdcfce9de673853dbf73730b159b2656047e69377d7c5025a6b346fb08831e64bc8bc34b75765012460d8135a4f7a0f41d768fb85abf17f5e2f5c3f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2c61867bca70e8662c7e5435a5aec020faae86fb079b992bf49d8497fc5f96abbd38a6f04f6ca8510e0160e546b3f68b7baef4ef0f404e881771cc12ec5ed3e3787c2d2ad6bb957cc59f8d56f0afb4bea49cb671cb42f4e8a0ee1dfadb6fa14f84a5b3269dd33e20d658ea4cc39499c7a39a4b5650ad7018d32f97954610f676\nA = -1bf5ae15f24c7c14eb59605136a3f679f303cd5b81e4a27465281d17715afdc2c231d7ccbc59f80ad176f4e0326eb757b52e3695e27c6776d7936da47e3a8a904f735b151422029535045ef489e61ec93f02e6d588491c8dad1cc311f52\nB = -3238dcafb85ce557036d19e42e7e7e473de9f9da6f920e18845dd010546868d2652decc94596cd2c36bd16b02c02559892b9f573bf21ab18c3c75591413d046b385d08aa66d849ab8adc9fbf788e837b047a7ce2b9c63f7fbd263\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c1d04b831b71", - "2d0619db462c3f3fb5973f5984e9a48493ff273a5abe17a548e185d751628899e2851e425a7d4b2c72d4d908dc813cd122b8f497e08e299dca9166f19752ff8cd9840a70155ed9e8c063a3840838b3679f96f1cd5f1cbf0e037d222029e02769dce7fdaea0bbb5417f85497d77c76a387c6b970eac15dcd128ba\nA = 7aeb60c134e84f289e419b74f99a5ce5b4aed5fc630d5d591ac7643251ad32d6ca7f052fdf8857f67138262d221de644140e9018f7b84879d74883f8f251303f65e06bb52246ec6a912772cb698b47de41c1826ddd065359f6b9f1ccb0cdf\nB = 17f81e53d9fa6201e4d3eeebb32267929cd5258d10f053e7c021c4afd17094f8ecf433b1ca752f8740f6d6bd84f801b1b9fd64bc4787b9ae5e5aba0b4318a63dfe27e92d5a3ade192af7563c74c9d6006ae7701240efdd6021a83cf6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = aef89874854ed34deae1b77286f9cb0e3017e3ae77fe050bb244acf4f30dc03504c73c1a4d44b769709bdb53811a5d0f8a76a08e6a66fc2cc4e98537ad6a8049f02494305b89a49a55e71fcc3f5fc42d6b478456ada9b19ec0a03f5ccfac5538c0040092771660312be5e51996073ff1a506d7460c57d54e10dc2991c028606a\nA = 18d3af14bbffbfcabdaabe44074b407d69abdd80a6eaa5954f0e45fac85af7ced1715c78da872f7a8fabaad3207e31f12b7195cdb25abef0a1e54d3b13349d997f207fe130d7985e2033cfec899a0af310c9827749cd22bd062eb0b1faa254de\nB = -85a7d9f08a60031e689b0e611d7f7f46e1178eaa2e6459602e738990c77f4d3783ac43fc04d53504cf67fccbeb02f9846756f8e32fa4a9316b6d3b45f644254077bef096a72bcff17ffa17070a4355121cc5daa2f782fc0d0bb48101db\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 14a85edc6297763547702c212b1a8274b8f85d53ef35cd1b01ed51039bbe030d0a1b9626ae2f571a43f1224d723847a1c6708f2238f6f6fd75db6656e6c703a5acb57f69717efe8ed58a3713ba2720d8c001d026d83de0ce5e24b67c41daacedaadfe404aaa9b672f00562e6901fbd0710c4303fec41ee3338100beb36c9b1ed\nA = -44414ec207060d105f599b9a66aafecc5b232b55214c1a5e1922f6b59439b3ff77cd3a327bce4f7406871196b90350e6dca9aae147ce03027dc4de7563c734f111d95171f489105de5ca80047cfa43f7e932917b816ba7d41fb95b4106745d700f\nB = 45f2cea1b9b75880ac3ec206740cfe0ecceb488c9155cfacf5885a8cb49be78af8cf221ff8de2328f4880479c031f830a3c9eaebfd83f7de501b7c5cde03c4720c56a676d331b2a13c4689a2e34a43fc11f62825b8776e75d31225ca7ff65\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7670c1e2e141d8f8f5466de8ae2e0ba2eb3eb7634699eab8415d3a37f8df291d00def88361e9fb64a2f116433dac3ac2764fd62f3201dce4e48a3b7019e5465f82241ffda29d5eb0462fde74dea3168f8993ccd4d090b9c31a5a6cd7e05f725bbc89479836b89379b422250ab049f31c860110df5ed69089716877fb0ad7b0dc\nA = -15b4a2f808a85a5bd466a342c4853c04ac0ab73f8e53a4a0477f73dfeb8d7a911ab2eb5d3d192b9b084d0e38db491148947c66f838aa5f460c37341b129137614259efa531c0e6ffdf163ec6851737037a5299060418d96da035e6f583e6ba79d0414\nB = -3e94fdf22004384f7881875b1d8f58019ed8afb1b6a31f5d591e77b0998f3100b34174d6f3466da44b4c7fc8b92ccc5679c26c146b704198a65a88554d24291adcf897bd758a035361f671a82972b5962002c6a828792980f86a64547165327f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 35b49beccd8d2010a8d777c1ff69e28e01a1bb78c6466e717f0a934bb62f9bbcec5ed29f9cd2c14d240a6c33b28c986eb9c8912a4927605532483dcfd31a50876e1819f3d7a0f49bd276ced5c4110470244fca52d2611ed7e31cd8b73e749aa70743b39e92810b3b52320342a65cad3180f6e2966059d15f79e5574348f5f66c\nA = 6fd078e3cbcda6a71a710e99204da640edc71a65974fc765999a74ab50a0e4b090d57ed0ee869c8da2cf694b6fab56e87c4af62fbe73eb8890bc066ec3460beba04dac3b8fae7e4f316e8f954c6e8d934e946dfdc9f4cde0f26bb3d40d5c444b03bfc65\nB = 14d8041a3b83468d2f44f150ad8d8d0a1a22035d630f2a17b70d5c3d557d3abc7e4d753e1ebfb3a3ba465520b84746073d211a67e079ec7f47c2cff9c06da69bb5cbafcb6cabe7e0018867c42e07931d6797d4499463e3cf786c6d5d6c8cbd600d8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2f6e0fed8a9720fbd83ce950d7545d2c6d5b271582194570424f90309227a51777cac974bca0ad3c1289ceb91cf75af73b0645cc20d71e7789144876b8c1bdd550328d9907accc316189e8ad81310848cddd2dbe362c9398d814a048f93f9368fdbec0f19ab87ad2a59d4066d738c3da3cb71d4716f2cd2336ad35ea1438276c\nA = 14bda9e4aac85b0ab7abece728f61450b7779d3b5fb83be813758e742d2ad76597f132aed91e20a75c554f0d61ec4dd118eb733d04942b2548b1efdb4dd22fdb543d9bc1e4bf0574ae2cb2c46fb98cc4835b6a074d6df1a3bc5443beabdc784d542e3349ad\nB = -efd765f8ffd72d041ac3244078b8dc4482233e9411b289cbc2cfc26fed2cf28e286835010438ddc9e7021ceb098b10c68bcc4732608ec1f4052df9362176ee14812bbf09ccf7c2882714ecbbf92bbff61c06e9dc35a368208a05dde949fa2cd091ce0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1f0c436379f6dff55a59093ff2a0626a9b959e3e3e59365afc33c7a7893f04bca863ec910c446957baa8de4e35a1f4e9c4a776ef41b053f03b775f327eb7e5fbe68bbb478aa4339ae703ee4b573d6931e47e09271d40239d527fe77098a7fbe519f5eda1f26dd6a7d0ee6833efe37187d8a85844690fecf9fdc3a4d80b921130\nA = -51eb34de29ba24d2b1fbeb0a1c324f4ebc69cda2dff971a315c0c2775d988b03ca29891ed0790f3dd507a1d26ead461dade9284613e45df338dd83aebfb66050465d8aee554970b43f7d4e0428e1512289fa1f9b23867b67095c455b66d536b91207b749189c\nB = 55259a1122eb7eb611a69118d3d42c2f05dd228d71c0e1e42ae3a8d3d180a95b74150d844e916ac85105805126e4b995f2ed1cd3fcdf28e1fd241dbe3125dfb3e4d90556256eb513a2f7c9b596719c83b26931d92bfd3573560e8bf054138f5d6b9cde72\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = ac321a272d2206df4dcd6ed8ca194a1049c1e3a20bf325fa44809d302170f850721c077bb5d792f86f7ab03ca259567397cc2fa1429771190bb632ac2c92d3fccf6e05e13cd33149994cda5f9c57da155439663f6a13c66f9da553f5038fb92fdba186ed9ca04b8ec87cba4c5a68c8edeedb94e38a6dbe293340dee1a4ecc768\nA = -19ac99d7d51456b00a193b3b04693c7e5436e05763f0154768db078ea5111cfe9eda3451091af213b9c8cc649d341de66c12ab2803ea39655d3d7de182a77355ca444c5d2778f791d39952a7a11839e497f5dfd8a703df49ec4d7628bfc25a992e94a6477e6be39\nB = -286d1d436f113308be594f0f43d7a05120639152b7e2f93058cf602cbdbc016512bfd23f7aa937fb358b7b602d15998ecc150f2b9224c58527c0c1267739e065e24236771e2c683957871637468181e6e896b513569bd004b9845f0f0e4c26a5ca123365e1c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3466804a1b7d1af8b6060aa93a4c325d9cadb33ebcc8bd991f9e44cc2cca8918411efeed0f005790d649382ec40278c8cff903cf3db177d24466c58cf6a56ffc14e595c36bfefaa2327d37f616b1466eb702f5c49170598bc361d892e18051b8233dbc5b3fd6832befd9a995bcef3b0f3beda6efaf09f7306ec203172e78264f\nA = 6710c19330d3f974fc377e28039e0c0ee0a558621fd67fe724c326537c18c66dc5eec60980e07d401ad5556a05688d2dbe7b271f9d5eda3032bf7cb7c420e7b5d65a195bc037090b6fe83064ac3731624ce2baaaa62a6eb07156ca12ee51d4321988026cff573ede9\nB = 137ca18f47a151363a3e8c52dcf024262ba525ec8852e8e406f460fffc2cf88f1999b17a5821849317fcd84d09c88ebb6eb0340120f113d7ca5fbd91c6a40cd790bce7b422552cc0cfd2a6417add2501db1667f2802e5d0f4df824adbd033a90a155cebfbe0b53\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304ed", - "d566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6f248a70b2cddd9627b32fbd130f05a604866799365f94d97f1eb582b28192959692a870be7c2614536a8de84cd8c1364a75a3927ef9dddbb8c6c87dbf526f2d3a7916384f2daed96002831173fa4a51863c28b4378f99b1b201010581d5eabd66ad1e328cc4e647bf5e0588bb775e130b4a4d029eeeeb5852c5742862ddbc3e\nA = 1f014cdd87cb33ffee623cf454edf2c476e91df279b4f0879637eb6e8e5ccab305186de67585595d34ebc195fb150408c4620cf6c7a0b0d9695ba0e0e1d7552ca7d0be3dd678b1cce2beedd11939891a6804770f1c843e16dc2ea6aa8e4043940c37fd3d950caa122845\nB = -8d8d9dedc80994fc5db04d8c935301e47054250fea9020bde8d5fef01f2307cbf458d5afef5210a369c396287c5eb453637a2d721085af3de0d75a5dfb5dfd22fde3b229d438439af7b296b9e68ffc982efc6c825556c52a735f8be12a214a06c4270824d5268fb6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a35ff7e232f047e575b200b9fc4c9253de6ac04c612b8a82c275a951075eace5e7d6664fe8f78301d554cebe7b996c1f4ec3ca59d8d12d7196eb3909223de94c220f0445d24233534af1c93433b05c5924799d2c781fdb88c4537bb8d442e6bf76b2d966827bfb4f40378a3f135103513da056bc0d375b1339561700d15a0227\nA = -58346cc8a9a1e5b8babaed8e7f59415388e0db654ea7cd465d96781c57faae7a8af8e7578e46f3a8de7bd1027188e1cc32fd1c0d60be24fa3289a12cd822a6c9a77dcf8799624856c27ba88fbdb047473274e651760581b44457ed048cf76c166d38bb9b2afd3416ac7e45\nB = 61951a16dc6466a9fabae99df29b7229f1ab96b476092dca1e4f8fc8e7404e2fba56ee66486d1f27f89bb3f86f271307228d7d6cbcff943961e177300b6acec1eeb46af1c5725f745a2d2af0fd9642f57a09c9ce6742114be0aa6e939e638bd5c7a92a7c206b2d36e35\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 90b441d8277eb1ed454964acf567067925881b5db0b446a7d554dc61ae87ff979bfb0e58ca1706123453e62ce31284a5a2db1228d259e27abc7fb5cc5848dbeb9a6808fa1b4afa844ab39b652abc41423c2833e1209a1674db518b6df7ebae315dd7f416df54e73088762ef64cc2cd0a08b1cb01c49d9299d149cbe84145a55c\nA = -1ebb693ea7d18e0ff4a9a51124ebb78bfa3a4635b75a6387e9fc745a2325409f927324d1289be8a4f5cf2d5c04adc7ead20564f97e453287f03e5ab59a6133584f970446652d05a131d7d382c47b7cb97580ef6710a532dd4f5a0369dd3db500ae5a3c5efb587cf0cd2638382\nB = -3916ebc4653e7d6e0a4f1e234d765d41e9e948b5acd7ebc73cb595559c1b20b037a3c8da0a7aebfa5fd327bdcc922551cdb8db3fb0a581fa0620ca2d2559ccde3ebc44542b4d80926d061e2a35c08c09547e0cd587c396ff2959ee93ea64b1e6b7e2b624cdf445988e1f42\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3ac61c3a028f4a2df6645acbd36818a2f76a3229d229ce22471760807585a909727411e8b68bfa4e76adc459409a101a1ce83900d46918e8d0903a163de87c07bbafbd60c7f536a62c59370ea53b6cea4384345343146bbf529334b4201ebdc7585b6e5eee42696400c9be9f496406a4eb51d2fd1b40466224f1752b181774ad\nA = 5a16d5fb9047949684b80805e5d962bdb939d0d0368b48517a2a826679c37ee0ded4fa83e657192d9ae84294e450f7e2f2773d1f13395169582cbf95860891b9fdf8f3240a16aadd1198e884f22b2718219d478e2410fd4bb98ea534a3626201959af099fa55488f5390791bcc7\nB = 1f67066dd06ed4a49cb556dc2fce22814754885a7cf6c13915d974b46b0e6269c0fafd688f45ed2deeb026a7cbb772c080dfd577d21ed2c81e50e7537a70dd550eb94fcdf626500040da88c43dabce13c82a93769a9e0ef66a471661292dfd3b3af07169e2dc909e43678400b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7087dd62eed6ccffc7e1370cca9444dccc4ff160458941aa9f49dec1a2e9ecce4cf50ac2daf06994c5010cf225cc92238cd60e1aed9edb2befb0fb354ffdde94ef5e8ad0415bc95851d59095a5c4850ec52a74c78eab58309f395d3078dc481feb9d30bcd9f113af7a01611b94d085e32193dec738a64c5fe9bdfbf5dbc98cda\nA = 13596eeefbf06e9ead8d883113d8ae6cc3da8b6fa13ab66681db5a9c083ef9e49d905ec19c39b149cc09452eea0446b29cc92d4e865e6f681827336945282fa6b276ef552363229a976c503b822e6e4a9862d3fb30dd0c3627ccb97a7046a6a679050a39166388a9daad5ec5555dbf\nB = -a4e574363f2e5982cc087b38110d257019962fc166c2d6e6d396220bb308a8a0dc7d90c5cb2ab85faa19b07ed7dc11eae9bf2abde0a5fed279e77a717b43d35e70fec4e18445e37741262d0b0c20dc4375371d87d839d39934f1dc41122e815f3f37352d04d0cf514738b351f02\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8495eeee238164082240ae1db1e3c1e36fb6621e6b714c9de914f9de8a587d7106b8dc5214f7c60c0ee231d7441e03cc26462e71adf8e29772ac95d0395722d2756f9f64daa8ed41d7ce824a572d7f9fd419112ae823b5b48b8aaae09fe093e9ed05918c4ec88ab159890910837ad0691849b44be95993682b2da2b124de39ec\nA = -403f21e1a7911806747bb78a4f20c4e6572d49c6c4ce071db0c8c91ee985e68a16e60093e4628414b2673d25c9f13c4c43600633af95017e3846512197c9515aaf9953570ce5861620716b3d80eae7de0f033772fba82652484cb3ce7cc189d1fafb14e044e07a88da302547f2e623d8\nB = 689d1b4a968b7c00082ae3a29c8571f826c4630c947a7767fe4a71af43a5de84db9b5baec0980eafd0019e09de1b5c56173ede68c9a6acf260bef3d9a03f4c83a33106c94ca7e1a8615b3553088d1d05a62ddab0f1e5a126df5d960f67e3b92981022e1f0358c7970bb2fd5dce7a7c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 397df584bcd3b2e1ec7ed89de624e9d104bd6812901e38c5740755ce91bd54155c0b624c590ded199590be5d98bd1ad4acee56a62d05d6b5fdd1ade12f7db8e3eb08c4a5996450cc1204be7ba61b768af0efd563ea478033324731e24fedada1ad6e564238c891494e85ded4feb2165fda22f75bf120856034a9206511885fd5\nA = -19cc480d1e07523bac502872a971d78bb26955c5453386f5d51767150e229daad3ab2dc85e0fa0cf6e72389391fe627fd2d9f263f105508642eae5a095ec4d88545dc9d0a2c436907460e1ea7db174673000eb2e0b60d57163ced261bd0f6cd8ce54133cfa10591f1fd27996353110060cf\nB = -39c45512fc7c9620194fb7ad22abea8f6dbff4a137dc4523115ad7e262934143cf1f320892f8c097a400d4099e787ea7041d0d69b6269d191fcdc8ea28340ecacab71058cb39a9c7362c848826b35ab560c27113fe53c497ca452397891c81365b6e7f07f916d47961e50b8c7c5cab38f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 263ab04c98efac12210beb66b13fec7c260c5b1cbc20cd732a511fb3786b917a617d6622847f4eed70f25982ef5d0b0d13848c62dcf447e3a1d491f4c80e69cec03cd318f6f93134d582210bfa81c1790562053a71091333348c6624d4d793fd6ef971d284a4ebf0be0771efad302015abfaf3edba017907f10ea14a46d9fdc4\nA = 7a354753e39b9ad1c0ad6b65575fc7247487f3ea320fa82d1d333ba8dd5d0ff925331994a6961c9c603be5775ef1842159551f0bfb34920b93d90ca60e6abd514650f77ee8ffff2bac0eecd0fe8ea0fffc6ed0285c9f3c3cfaacf338043975457d62f9c8dda8cce1e99f34529435016fe2ed4\nB = 1a4384f9620567c698ced05870b4dae983d8f0df6aec888353f9dd6ac8ad54340c3ba8346bfa47bac38897f3963fce972f6d55f3407ae03f5c7637be1a34e483e50dcc27148b76ef079f117104162beb191d146ec828ad5c5bde5ee1683a031d554c276d837bf1f2f622cd11baabce10212e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 91cf4d1899e170bf75dda0d51a6481f79eb94c333b876382c9d04681073e949191223926523f6531f0a45765d7f382221eaa080d7bd05a3c19220ebe18802b15d8009714e8e4e9872223049622ca02040eb041707c7e525f698cc", - "361847c66fe3673a72e4d701466bc374f55fa5437216eb59375c0e2c4f7020149d0118ea72a\nA = 12f35c48024e8271e8f9a60a48b5a214bfb6595a837c041b230e6ac87a4c1d4b3f93a2d3a193c750c9857c8627d0f7c454d6c4f224dbf14a865eb83e990b1d9b8bfb729b8d3dedbbe9c95032e4d60676c2baa2aabafa698392590add3b83b521a7a5e7d6f8af207e44ebecd735374acd01ef5822\nB = -8fc18f92c0613d085cf3ee6f586b39b99ecca864bcbe60fffc63c585e5613df68f3534ad46e244916b1f9188507a3692526c9e403b8e93480b0a5a6297f65215f1a5d8e20631a9d559fa1acc15a98c9397761ce18903f393b10444ba51bc92ac44df90d4cf0852da9d75902230c6de6f26dfdb\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9af562a7b61c6c84c91bf979f32ba5d246d2ee2050f07ec2dd5cb3f9496bd37c3922ecb2b5b17085a13e93ab2dac6022077cc18c621cce3a2d2247e5e89de8692a36f596e5dc7a6969a4f3ff0d1580eed380e6550c6218c1938caa2b7ab401ae6f520063c811088504d60a19da3b5018d640ab8d340f35d1337a2ede8bc64bf0\nA = -63bc10b8fbcb391dea305fe61b404d3bebd035514a812d0e1d38daa3d67f9f1bb8f02d2979270cb9147aa51d66ca73d4b5787e472456a13fbe0d568e92b622439d33ad3c357a56dd26806ebda7b3bb592385ca5dba7e5eb5d85eed0a1746441e8d56e22decdbf8f4296e30d222da5af17c427e832b\nB = 57a602bbdefcdd00f42ed1e2cbde2ba858d171804da56b0ac87081424ad1569df1308fee7c9ed349eb496d5409c4c46921f09ff0830bc9f57e920e17df16523598fd90314141955ddb84a1522ff3ebfa812cfeb6670525123476a739f64ebe6a5f1fc805a880f8e5a71b908c483a121b38d05cc2c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b395c9f264172a3653af6637e72c4c8e564d1ce68032a5d761bf546e0c4b51b33cb026bb4256fa639ae98e54e5ff7d8921ae411497272b53d97c2c44b5b9ecc5aba43dde201f64f1d033056f19ceb0cbd04decb486a1d07ab1c64fd213d7eb6db9cd11efd743462e137f368acc4ca0b49a7f85587bbb5ede4be1616889e2699d\nA = -1e71df5f04001f6468c3a192086bda948aedd19c5da9a5286856f30524238d95b0ae71940f2af123315ab5d2fc61964d3e970d5858b7c1a78d0f2cfd10cba7ba4830a8c19a09b59794ca5d7da32cd8376b5ab06079b51cd9819c0021ea41a9e43aee147befdbb17a92cac7c7767705fdd908bcd291fbb\nB = -394c187308320ba1b14d91d75b8ff993dfd57f9c84e8185f12bf9924e046629ffcd7174879f9925bb643988259cbe9dc9277fa83a25012f91159b012f1964aefddd5a94ac6c2a55a22bbae93085dee079f84cea1d53dc4771901db9a3db5a14eb17c25aaf5377e2beaff6276cbce7cee97a9b8f32737\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6602ce0fb5002eca37e85b60cc871b7b2eed13d38c20a37a6e0886ee4814f3ce2515f8714c67ad81e8c3abf6a00464e6a51b15e55b6c11296ada43cf459e15915026d3260cce8fb796241fc2b0bdd2b65ec04bee3b7ab6626e10597f3b13b43d16c34afd5b43a219917626c88b24c6f8392bde1b2e65a50b7f1a8dc5eb096702\nA = 4855ce75a3d7dbb72a257f6291e9f6ccc158647aeb2f8beb3e8fb32f6f59af1a46617b77440798562d6f58bfe826d3ea7dd28daee8f5162d7d24ae6c24c2deb2669b15898689ca789e2005903f3a94e991e7d3c8f3ae6181029d959bb15e71d7ba94d2dfd3ddd10f6fc49a65798b5f6ffd64682c78b5d91\nB = 15b3e9992aa3f042fd58ff97a8c04aaebf46b75fdc38caa9224394a1805cc26e4311bfb498d5a04d19396e98d11c8810620979362df82b23a115fc1711b57c7a56b8408e2682a2edca36cf9311addfedd2d0889a78cc1ab170d1379245de6f1f6f4db815fea9130463dfe5283f195e6e81486a1d39634aa\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6a81ccd82f00d829bac186fb38b85097d52afa3ca83a026856bb83f94d6af6f6c6f3141d433f8fc159d11397df8d2f44c769f255cf8148249d8e9fc4f59ec3bc8e804d7d5189e71e20b8d0e540b59a2854ddd7feeebda5a95f17605e8bd5f311a63cc2e4ce23a51229d0a49ca04982c1bff79c201de6cc6150b690c98106a39c\nA = 1f1589c9b5ad9d878631cb03c23ea7e94680220856285668838452a63b726e01709588b38e578da8a4845aa5cc2e4723beafa4f81a1a2e463f67d9a3e432de7064ba8bfcb943cd9efb0e5a136649cdcf5e85a667917075804991b997f318752304f4946d69abf161625ed0c03bf9abeb4ef28034f818e2a643\nB = -909dc7fcbd27d0bf7d6a3d0e2937ce725b5cca0acf78c103d633206cb431e2e2c785aea4bfe2042df32417143de76b71d21587112f36d067f878e556b94ef63d59a07d19647593efdba7f3f5324d64c55f93a283a0dafe080167f6576053f9beb326994f4a1d53e18e3f3e770e69450bb70f276d128e48ecc\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 69139f2e10726f83300505d15dcbad5b5f284d1c06789181683b7b8caf35dff063dfa4968c35facf32a3628dcfc19b3fa4c30ba0e030b06773832a2631529fe0c0c402e05a0c4e9446a8b6c22754c70ef540f90d903d83a2e3592169ce6b5edf939ac5ff25b8bd48aa2425321602a9571661a1109e275a3b3039ff0c2f430b18\nA = -5d02cf3969bff8789850ac898c00fcb3ff1fc49a22cb243ad18703bb8fae25f83502bcdd885417fe46e8237fd0b444712c4fdb8f4972dbf9278a83eb305efc7a8210ce55167c069d1c4136a9b66d0c4dfadbf036c079d12aa082fbb42bfb0098006136a61f3da43aba3d3bcf2f5ac2d7884caddd0cfc28681d33\nB = 50b369234d993721288662d83298d99b9052a0a66336a5a31b76dfb20ec2b5be3aa76f78b2c17c63d78402a15aacb585be5c8d2e7083145e316e71e111fd34f5c79363c4591c247b1a94b20ee042d840c42a3001d6c8dc7cc1e1348e0e3ea8c6551f9d24af2dc2d0c38a54ef065ff048b148ce4f11ed2b549c50\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 87de406a6c957e85c759f8ff684023a0f98e93ad4ffcbc6fb0038c7a7ceed2486f15f36555d286338aab3283aef677118f7cc3f88a7ff0ac9fed31da6786ce895c3c08d3edb652bbc9ac2b44c4cd24ad281ca3a8e8e6e4d730f4f0c25487cfc1b2afe222934eca8b1e1572780dcc149422a88eeb1bf31065c929685a0a97ac3a\nA = -1878e0497aa1c2942a2e6956957c876dac73c4bdbf42bc92498f29a006bc92f788c24a4624b87324a7c8aedc6b2c0c8a1a442aa91557aed9bf2c02b6664979e8a9a21330dd839f4ba8f84515fa6f7db9287f7c20f31732b98fc09ee7796dc524870dc35851814bc57e1a8ac49d8935fea04bb08b8760df33a98149b\nB = -32f4e94bd073cf3f70810d9af7a873996a0510109bc6fdebb855f27dcd012c59507491152d30849d75f95dd868992c6fbbf29b1d899cfd401e9e7f4e0436732cb4cc9e6a6d6b0cb63fb0bee21e422b7f7b7b14dc5d2b6d10447fc4add390fd3c8e7b06f1d9b181adfa8d04459ed051bbdc9666623b00e3871e597be\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b456ccf9d066dcf4247a21c7f3820e324ac9cf004cecf8dd1f6c3aa40c2a33e24c423e97190fc71bb9fec21d36c5a687065a7877237a2a05e64cabfb3b20bfff0b1f5ef2e9adb7edcd7140d1047b0919a2c770579ab44a08e5ad9f63a06f90ec7d5885b91de5e524b2e187937609b4b81d40a0b33e31a48d7b9868add75286a6\nA = 6c484e3c6b530dcd3644b19fee66c41c7c2c1dbcde574d87ee13cabef9dccbe5b41e25c32c6a56df23f2e87176afd28249e5fcb918723707fca94d7e2c9623a3493d395db802a1b49d550f52c29666f785652fe81afcab00a60a5b50cbf523cd13dfa06d5a5b0809c68ff7264a2cb35b8d52284172c62ee658e8417e6\nB = 1b4fc753d0530bd07094bae09a02b1ea684fb4e8519086b1e2ed9d59af011f61d1b94ffca6f354a5b428417b328bb1e8af3f6c7ac9121dae58de9f1dcbaa9c73a357f408b870e62b0c7db1a72c4c440f2e6fe90b199b9dab29fc23927190d3f2bf8a7ee926a152e64474283695614ad696c85ea547f5f51d02d1b823e3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5e7c63276f350f04816a6ed9f98507a78314f1d99081fcd906affa3b8395fb58d029ec657af82e77ef45611bc988095bba9c26f25f8fd404432fecd02398e69635f3315a824d6a98b33eaf6a91f12957a5e80cb48d5b086c795eb3b1e04da5432a7e8be3d683addc586a44b62", - "43ffbb7a979bf9664cc7ec41e75f267d58a7127\nA = 18efe267d4c62576294f4ba44c67a058cdc0bb44c48f4035682b2d6b8a63106081af43d99098ce133f8d7f9cd04d4dd7414f704e32871d43d6e5d73fa9f447873168b43b32d6ad19378d74a967f92ec7629a690d29a62a5a6e734e9ccf5b84857a00d97b9db846b057004b03d88b827dde717fc30e6a5246c752d65dd625\nB = -ebaa580d3eef5361547c692e107439c8391ac0a2d1cec0cd275d0be69133eba8a94bd186ff9a129af3f5a015d5ebd30215643554d7064635dc11ec7a8ed2200fd637b099e534237f0495d2b629abd4c8f84aa1d925d53e98490d02f9fe51bdda08b043f67f0903c0195fcb886c04397d3612e4501ab8c7b7db69f781e169\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 76fcb39f94dd2756e8266c025cebe8e801524a757b976e35ed45e3da3db720061cee9037fdb34776c704ad2059ad8920e400bfbf10eca9bb157eca7750cc31fda06473bd22d4def80189c47ba32e2824c721425f225563df2a2ea1edd090e01c0bf980677db5a5dcad37d21a68e2832d1012586f506480e929b2fd9bb4aaddf0\nA = -75f903ed9bb0b6db8e3be16e797258f6c18f6cb7b16f835f04e3045f7e4974d7a86a63f2ec351c88fadc0635b6dc83a797cdcb5cce1a1674f89e44190991e0930575b19e2aa1512bbbf2ef6f8c3e707b17516756fadb635d8c6bf9caddeba14834b5950a4d1e98bca79a4d15e5fa5fa3c1727d7a49b33d481d32fb14ae4164\nB = 4ccc582c8460f7def2d26167b68788a681c41bdf6dc805dca83127a18bff6f5ebea6db75cd959beb859637b200ccb5c7644d571f436e46a357d027edc9769da226278f7ab947963f7caed1e7e70e572980e960e9764a40c6db67bb526694b084976142471270b2331da563a10427cbbb38e76203d7da5d67487eff701d75188\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5adef30c67aefea4da3884b8a1d0ce6724492bc76b477f1053621e7d19f3cac15448e9401d34e05ac4b508b9d1db9a8d323cf43722e0af6e3c3b6d463c6007449c3bc3236d156cdf988dfc308a1b4911554ecace52938a7b10f463d14f917ec3d9fddcf6d33081745009c59b58aa22bcd7dd8c3bbd489997d4e0bff5473ab9d5\nA = -174e8e057a1d66e22eff88de26f43fde1c8efe5611f6ba4f318f027f5a5818df02ec3f014dfedcdfc8c143c5005c3c5098d409710967c93474f5854c1113fe4030e6682bd56d389ca8b9a4587b8b9262d146bc92fcd81d75c3bfa4281898f394f45d5dd11cd4c7344ee7a933ee346bdaeb6f5188967c388b919a0ce6730c0bbdb\nB = -22702bcc4f9d5bc6f803af6af8072780ff7de7a346d6b9293ca751d6ee3a81493fa86738c44cf2b7be4bf14a55a4f8179c35c09dcb1485f4c08ec5e9f9b1efa91f4b5f15a31a46e1ed71cd934ba6bd271bb22bb5703aa468d297f360ecbb48f9fd6c572683e83ebc3d432203347dc62e19fa06f93e087283347950829d4256bf5f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5c2f67b1607776c10fe2c30b112e541c4d8229f5f99f615fa02cf715d3f20556a28eff5c233c58994e9c6c1fcc37b3416b0875b9a62fa5a09a4b8f9e216487203b387ff97fad1f39f674ab19c5e34cb2f162e6b0b0b0084f0618e64928423b73b189c744e3de9fa50d66f45975f68b14866cc16c8c6c722a54420adf027880aa\nA = 67056e93b69e8a7b789f1f8b835d9c6ecb7762f844d656b26df9844a60bfbe0d55684f61debeed31a24ef4246485e8a1d43d49eaf97ed9e7b9f2d2916a8d85b8c9e8ad5575cf5a3fea42392e5d1dfb23f7ad41a7b56a4f21e2828aab38a602d560c99783a4f807120292ceae366b1fbfb4be8e5d4561bc8944e7f17ebbcb0fb6296\nB = 1f874f244ed6cff9f910ba9a58db0dc0a7435e8d99ba6412e976b8f64d4106d3c5c57ba079384fced1c261aaa538e131734451fe84fd3cc5cc8b3ab46b2031f888d95084cd3a35a61092672a9118eee4ed1a0df0409e3613b3ef45a8b16b71ec892755dc3f83c5492b67fb9a143ee6102d053078f4875636b20b536d5cf851768cf73\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7850019c6712f18eab877faa8489daba23cf34b512a3193852508185b13cd5a2e9f503fe8d61b74b5d3930021a5b8c38322aae9b9b1b4814fa4c2c5bc409b58f11fc8fd7854b17baa94a6bff5f234832f9468d90d148fa2bfed774ac03f2dab6a506a70db4ce363f932adcae202f04fdcae968f632dd674416c23d4e21345ef2\nA = 1e378a0f27e6259763890d29e112e3d8d2bdeb9994c49fb67ab680b6e71a52fa0a7db886d3baf52f36d943b5430ae8bcd82e229f4197239c35678eed254c5816722b995e9c311be942f8124e2f80c1e59658433a57f346adfcdb83202e55457308161d2f928b60efc39538a6469f90f1a868cf6077568c8241623896ddc2705cf04e4f\nB = -f4ee37e39d4cadb692bab5483ceaf0258b068f2c0354c540438803780c983469ea28324ce7e209c3bf55b91f0a2f4544bf318585e4514333eafb9b8c2f02170c620e9b5280a828ce1d8dfc64ae9c28577e15071825a85a59656c5b47d9a382af6b78a5b3dab1078dd647e0b473174b8415d401543d30a4018cc3eddbfa546d0fad9cbb2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4c8f8b671443a3af5ef5749885ce5de8e2afeadef9051bc49c0d7e72922d049b1accdb79d82288e472b07578e8b6d2176d6cbdd7f0caab593dc0fd9224a94920235410501fddd6001b62a7f7d8eceaa7a8e4c0de52029fae68656e8120972b5cc1c2e909c2742e836f2fecfa51e12e4f8a2ec7e69eab061c81785374ac607fbe\nA = -5769eae759dd6bf94468eae94189d3396886d4569b0ce264c22d39b623be3abb01bd5008b9fc86701a3373f7764118becadcc69481cbb134c20f669cefeb376dfc489dd4ee91cb333d06afa391dd322abe2b3b715d11ee372666473a473e29dd90fcc97e939049b455be52b3f288db306999019c1177ab5820d94859a9d2f050b7ee1d4a\nB = 44adcaf1e2afbfddae19b23cfc0f0ba1f940d32945d0b541db23f3a0a9d06fb1f67ade9a8e620bd96f4005ced99430c7a55eb7e93a701c829fd5b9e55dbb4d3833afbcaa0d9c946916b1a86af4a6393b1155c6439b8b82260e09ccf0ce5d1c4856f4d524983e4b0fa123267694a1c6118beb8be26113a02721a02d7b0ccb01ec6e9c0f9e19\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 51e25767b8d4d7b2b0c2652d9ca6bfdbfea06acba543b1bc8d3d25b2fe5f2998febe1a6e742abc3f482b4267854c2223a5918a9b5c84e0864278283bcb5bace0c046db1d0240443404fb62d70ebff3ccc655e5f5977958df4c878d9859a69731744f3d33978ac31551487270bb4fb56ccbf59402ef9fee42cbc329420180de08\nA = -1966812979042198f70b3f1238c93ac5c6e5749f1108c2bba869b1dac7680f910e56318c9b59be9212e713a348767ba6e75917fb599e929ea2144880d18d4fbda4f4663c7abb49b02245169f385e09098a4e01b56dadfca8c803acb7cc244f3c98bc17440ab2afce318476b80e1d0b4ed9a8d6f2a0be64633f8faad5eb48de2681a38a633ec\nB = -2e4f5eb92fc34c753c61dcc826abab6fc4f427c6ac7e73ffdf65b1037464b2a9a0b0290e713d81ab57c0e1dc30e76fdf96046fe10a34cc4511398319ee34bcaf73763a9042fcacf59a100c43d3333ffb3743048e8df0dc61fd0da3f935fadf882ffdfa9f0f42980c1af6edfdf161c4b16087e2b14277f655abe54582de79c51193e13169b55e6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 33539b5f38a9943b15801d449adabe02da6e21651d96acd9aa40e866bf65015fa40178399254e8af6bb082d021e2a05da0f45b699d193b70112e114f0d25287476dc0c733c5cf9df57667ad0d3ffc4ea2f85b43cd10459cdca9465b0974e578c00a6e275e0b97ef2a4c9886aab7b5947b78a88f84a3f1d8c5f26bd07bcc59886\nA = 531b891fe9e8db322cec59a2115574c7a304c423e6b11516906b840542b2c608785e2c18033262ab9cf68f63edb40ad4f073ce8841db602cf8fae0a6771d741c6392976c9b333ecfcd0c8e9997da40616ae2a9e0c6be93fdc7af0dc0668ded1e42a9f729c70f74500ee76a91d3d993c075c2f645b35792a20edf17c157459e35c0a48da6c4c6f\nB = 1a6fdbfed1054a0c5758f92f72db7e5737b0740c4d8c3ae4713366ef6709b21eaecb6b74c92541a9a0c99ae18ac6ef7de79d4c84ce39ad59cea9c203734a99bbb895916275e8778cfcf7fbb7b7d081a677769e4ab96bc7bcf23303100e629fa8e07f5b8fc2e39c7b5724c72907eaad09d3088783b3118e57c9c8ad1799b43a13f73864c5602c478a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b92982304", - "9d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2eab6018361f557ab06725ad90f6886d4b468ab1a193f8fdcfb4ad15fff781c8681329a27aeb5f03a81d7c404b8017b12fe23165e941ea767c733513a07e921aedf20596763f6f977316e37bed70f6a617e5c2757c229c59b3d7b1fe8755b5f65f7f407f13634aca7c8a267e661ae2f77fc5a95f56cd6c8458119df587478b1b\nA = 1cc779145b2b7bf9ef4c9692845e162329940f96eb43e04db8728bfe736698082aae6b6a1b3c32867c293b08547a0941cf4059d2d567840ab6ea526e3724ad59e715a3782ca656cbb739dfdf0c113a18f0dd62423d4edb60057fcaedbb852178d38f1b5a232842b4fc645cbfd97a8cac0b094b870064302dcdf23df2c9e9f736d93409cbb8ce9ab3\nB = -cbba16086b51bd83d3460e51cf193ebc79b826e4f30978274eac3b2dcb04e9d7b56a1449b7cb128bbfeff5c4720bae45271fcc64085d3ee501f0f21fe73cb7db5f275d88be55c339f9180ea21a8cf3755a875331931b75d23f57c2030c89c6f9c1ead431cb4dbd4480564c83f8470610e5673c7eb6c0fe7351ffd7ee460df5db7872c67041aff0227f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 96fd93535728b961b4167be8b304e570cc34e787c12a9a5d76e099b336ed6b837cfc246c5bceb04b0f4744c5da7071fc01d70e342509473e5bd7c60d6046c9b4f21c5ee71c4e678447f837db3a7694fc3936ca733efdb7d387f0f6e263b3ac0b89054a826da9716691c9d580ad38d701d08ca090b6c59be466e1b9833e75d820\nA = -6791fd686f46c3773fc8d7f4753d178a93f6fa4941f4305d9689c2a305bc67840bbef80ff05c7bc6de3a595f73846609327d28540cd705f5aa94a3ae5915ef55304c37c4c43a4b46906889331ee16585629bb303673d439de9c0236f708fd19a977e6e1032e0576a921853f7dd328979ad1f1aa945905dae93a82b3af9451a541f544c18ed2546b66e\nB = 6ae062b39c77bebc2fef05743e6d35e14a31c6fe1fdc42d8de2db94ce70a6d60d66263c7414b1081ef2fa6ab511b361b8baa9c71ec628dba5bfd772c440baefc2fbed68d40897878232d9715c4b7e7c9bdd41cfe7b6986d825f68be8cc16d04afb0cf593f3028f3dcd91bc94923f3d7211aa5f0f12d3270e8df8bc191808f0e266c4fce2af97ac7ce06b0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 949ea5f645ffe5d0d03359d51a663c7dd6e6013812a47be309575e036503126f48677c68c4ef6e7b3f72d76657fa282ad5881263e649b5297da82e24298300d032af3f5e8309ac7eb597b16e257a6f7af3476a264415aa7783433e83be57ffb3fdb404a9ddc3527d6a9c297f8cb7b6674961b3af837ebb65f218147a46c39cba\nA = -10f59ba073126d92a201529a5374500612bc59a9e66322c6706b422d35a4f82d97e668b268f5527b4641c6099c80bcea504234f3c1e3fd29eba0f161da97c50aea542becba499f29d4ba5571873d4dd9eb3f48cb26fa6c929a704fe8e49791b2ca3293c2428d9cb453263935c9c90a4a2b39d23a0baa12535845f907d42b729033a0a1e74d18da30a88ed\nB = -34fdf9ae6760d4f434d09ce2a7760ca2dda14bc256015809745524dc49d841b07102aefe5a1d0182e3e09d4d45b415e46f653185742b9b8ea6960160752080e5c9577a12182ccf1a293407b534ea8ddd33ad16cd19ba537d8db5b542f86a2a292423d452bf18d82361240a7efa831518184572c5a8b73b108a81d5036b3b530d98bd47c7fb2123418f12e05e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9ab739ddae55a0d71b39974628d4601122ba6c5035c3ad0439691317f23dc33c0014f3e870a105e4dc1432ec79693bac658433b21cfc218ed411e003990b94ebfa87767f3614ec19f5bc30704adcaf85a9d3d15ea764c8f0bbd52ff388659637746d39859398c79016ace8c6f97d3a5616711a235b85f334fb889b9280ccbea1\nA = 76b15a0aa0f59ec804a5e9a627e1fed524320b29120b6789f8e71b1ac4e00a9a8c826919035b84f87d291e2f35460bee181342136dd9eaeb99ed00c6328b8e44c49ede3921d6275f6e7f03de179fb2374ae2fa6c58852fbb2649e214691daef945ead6c8bd5a53ad2b130e9eab6ad046ddd6b80874ca6515322bc171ee32749333669de0d9c883058423579\nB = 1fe2171056ed4585a143b6b2bb5f44047664f64d710dfc05c18be5840ef9426ef05b6e92e4ecb5544ee4622e9030153dd9827f2f01ef38e62b88ecd6c46b4457d16644ef6d863c226acfd6928a40de614a5853137124fe69127a7f05463eaa49bc742d8f7be300d06b302dfb0ba86801119bcdc01b516afa360aa8b22b7c6c1839cff859ca1bf26e3f7e030512d\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5631048ffdb2767aa04d59d8a5750016b38b983a2d53743ba4de5d93bcfc8ec30183a84bb1e290ef9c72c7ad357728acecfc613a6f9b3d712456d545ed54a337930937f4589fe41e66ee930db3dc10a4fe41481008c69eced65b9d1c46b8574c5ac8f7d94025d8fff00ced17a5e17508527681bf94c2dedd51502a2c4652538c\nA = 1aca12b1933f25ea081e12ff4a4f6f9ce379f96d976da2ff7b8eb8ad791fabe31c1148fdec22dfd67828e540c955a1e13f40c5b125e1c7e6bd839bfa84e5bfb58bfed76058c6db77af7a34ffd25fabd60e19f65e1faeeea6371d7785f2e5bddc8650a7492e06691d61f997483661eeff54a30656f1daacf31182486bc40647975151fc05d2f64b50e632f5d5c4\nB = -88ed894287043e7e5cd2eda3c1e5c97f85809f7a246b0c20891fa9a024f3aba4ec1f3d112580fe6ba6b0bdcaa1325ac7ec9508aa88c187af08e4f37631eb6cc97e4481b18f747ce6d35ff355e425a4833834ffb8d34a818bdb015fb818ac9f58feb87020234243aff912da5590ea3f6cba74f1a9fc3ffa2b4aeea25479c55a3b572621e75d86d8c8f6ee4f587e0f5\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6ce341aa4a571cd5bc110dd436acaa09f409661967de0bd096c77c60db58b2b0ec95cda50acd7fa20ea4266b2c579eeb6ac214a75d40abbb70845db74c4d6c93f8c545add269d45fb15d985e7e630d0425565d06dad4a3ff9835411e51fdd9780c24f466dbf29244cd1b8c3445af181d0928db399bbc8632f7ebcb9d48c0b754\nA = -52c53999b02a92d6254557203cb31a21dcb896495d1f29f3277d19129ee43e521ab9d5a297204a844a9537d63b74686eceba72ea2e7b98ee8895513395cf7c44c99348f5c4eb657874a8115f0027d6a416b8a04a1ec0e6809b7701ee7d41e99996e307bee9c295ab3df1faf674e0067d0ab3bec4da998580203e33760870ae472a3045bbd66e352b8f4d284efc00\nB = 4329d110504caeb71ce0453b0706ff675f646e70a6bd9575791a38f672eff226f4958f8b1fe4123c0001d8f8595d8030d0e9798232942725a9b9d654ecf50546adfba7103fed796b455ffbb4c153e70f941bef7953c8a210d6f2f4ddf5d9a79d9938503ae8f24d69d5d7df1c988630ed960e12dd877bb80a1ab0bcf6db67e0c0578fc0c40408f72b19052534da8d31ed\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4b9fc1e0eb4be199427c48bbe1b53948d0135bc1965b8aa5421a4ec704b13cf934c650405ba02ad611b0f29d46d82d4a1fc5a84651a29364524e37be2fc7001cbd3c792aa477802999841ff19620cf66dd2453c9b05aac349b9094d43b40e358f32805d87cea3cfa98e05240ff95ec57d88e0a12917628ebd34946eb1ad6799a\nA = -15a223b691d8b3696306b0ccdb52c1d62c7c2d1ac71e5f07cd8fba960417b42fb5ebed5eb9469be67f231b5254bb0fcfadf5ac5d2906769e8bf8292f0442986cabd88805a162c0c1f60f9ff0bcc2029ce33452d05f754375c0bd147fba745bf8a0008792d4f90d0e0f2cf391f2d7865705544f4a220ded44732321473c0ae7870394d4e625df11bd0923340cb70b995\nB = -340e5ccd644849d982bdd455ddb3b9a23ca14e168bb87256bcc370ffb6b7fe78fd062b3bcc1ad3c8c3b8cb549f2baaf1b7f0f6522aba02fd35b651f7de52b3aa2e0e40352bfd6ed0f84a2bbc3b3a396dc8512ca1db01cc69611925f1037794c82a418f10e0d994f458d1f19051e8bea32b90ce744d46718f42e711c094ad0a1ee96c88920188078f1b044ccf307e4cad7de\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 31c090e5160faff9a136a7a482b42a43ae3c7d00c215cbdad28804be0e7b12b0b3af820c1350b1622a22c8875f24d48ff16231c826d1a946c66f70aef92d4e6582e3ce9213d907267251ac74fa3cca9f1c8fd53fe9898aec19936a2b797fc345d68f0791cc740199be39c05053d5591d874b415e62653b04a3f41e263d00f230\nA = 5419e87e50b28b6d24927934b541d8de548a8f4ec7e9b00aadb6d23f2d33406177d3fc72d29ad2c2e141ab2916adfd30ec4791c626af61d8d192276d632aaf3b54e2ffe83b44f", - "6f1ac441e6823b6b58cc08fd7a0af945a02eabb5aebb2c7ff0622a17b38077cd0cba906ce23e71ac7f4da40ef6066565b4cb3a62ebda28f3629eaa251dbd9979b123a5447ea20331723e\nB = 184782ba4daf429cbd13ac13fe93fe5833f09915cbbc707feca3293e505ce9cf0b4b12ffc8b178e0a4617f809be53d4895a4182e7a8a65043361e654befe8b01429ba4b7420193d1d7d90930ee19cee0316f33a5795335f5fa517e1ffbc99b95101b0f936353afd3bcfec34851ebff1ef02fea991a01b587d28640c935ec91496d1aa3ab8d38a6ac75b3a4198ed27b9019bb3e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5eb9f3ca660de481968a3c7321281f22fb9273b16fc10d8eff1fe34842364dabcfaee4993c1c8ddb7c8d6e509a8d2afc005075d5fd3c4471f0622753c7797aea900e785ceef905e2606f64f34e47239c40b74f07e2ca70bd5a18cb0a88780489f3e98232221f65ac9c5ce703a256b7b75eb1dd38778d8bc05a37ac9ad8d36b35\nA = 1c73d8e3d5db127a81477a5c4c6d61ac62af446981773ca15a9a01fd5175a2826a8763f91d68df28ee606e8ffc203305875a238d2095345556f12f3b5e10c5bb6ce3f90342ac74b9ac057195c863c4b9d28ca1d958a98649c7f8897bc6abbc39becae963f61b33bab4fd20d9d0e5464f21c2cdf06d00f597dfde45dc5919f5124f26888b12d72cbd2f57de3f2de7c014f891\nB = -e406fb60e35f0abdd313b8431f4cc89fbb034daf71fae0cc727e9a93cdfde53566fc74e48f4cc2111fad158c63293bca0b21b98416381b81d2443d0e91647679481cd6b6869b37112d3b6e575eea7fbb5bdea422558d817b49ac36a829926553202cf9dcef09423c085d26176a89be741ae20a434ea461def090dbffaf2e2ef97bbd4ec779041ed69ec07d125c7b85a2d215bb0f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = acf9d363fc9b76ecf7e61c33270031340e66595e559dd1c9dd4d2243819b660183521a4124558fd4b216dcf5c52c4127fe517c48cef428b9ee0f1bebabab487c968a80b9815e82c12e807c096974ea3893a8d5597f745365c352a6bc6ce92479176092f02907538c5e784bf26dcde7672338f402753b08de8aa21b9480df6955\nA = -7c03ba6e3939ebbeabd35cca277eecaec31f326ab75f1a29e05af50c4e62e0175d4d6a57acab87cf1fa3a51791e9a2b2d4d5db570ec3941263902b0c74544c323c106557cd5139d2a25f3c3ef81ca009d4e3c16f1abf6e2b5196df1b30def46d61eccdcb3741a6dfc8e8c5e6db68ec29c82b0adf6e35ce7aacef8da806b3b58bfa489d319869b20768f8eebb604a9624d048f9\nB = 4e021959da96ebeaad17f9896ed53010d80ed3fd4c3a826a266e82b80ad81b3032303e7c0e58034a652b8aac00c08d42a530039de60d74ad349438f5ecca1256342ded6f30e3bd2aad5bf2b49124cb27f45f697e157550dbbb37f5aef0f04839aaf1ba43bf1e77a1529818d0fa91d940904eda6b748e5c86cd1b37592542c43b7b4afe2b8926fef6dc01784fa431d43900edef27f8b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 24124c69aaabec7a7b4e7a82245f6cb14b199852a8b314a7b8d9049cb66096d5ac93ac75eb58a2004de8b0fc8375638c0878fb6a45be8bfbcc292e3571df1bb8d6e346d5595fa395fef983a365e4e868154fb3e337d47771419e7f1dd5e4220900c564d7cbe8e7792ab288f99d265aeb296c5ebfdaf08b88d9b30ac660cc3ff8\nA = -167c959417e9566c93e7e05d2a410f4850e3a313e516ec958c3d2fbdecbf58072d05691c68981e176a867d7467091dfeca11f695f750c8c44ebc4d08e39e679d96c4791ceb1ea3b89fa3ce26f7ef214c5368c03ba694f7ae592bcd8ae53a66cb3eb1e0cd3c105faae6eb7e7a8fbc88248be722406f2d35e46c751b5ceabd992091eeba15191ccf6dd61a7ee0c624d43b188c42b6a\nB = -343940f3b2a5f73a51d6f609e8af306f44ce7b5c2e79edf6f4dfc07866dc5c4b2e0ba48099b5503af87762a44ae451d166f8914ba25b3cc41a766583bf73d27e40784064582fd9fe952fc00e9aa2d4e4f1ef35818978e725e69c1bcf267fda4d635d1d292d54d3ad10bae9763dc5d7f7226f371184465695f2d384d749fe07967a1bb64df22f294ed88b13600c7068d881f713cb8e3ce6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 50cac148215963e58cf6d2ebc36fa518c63a0ab8fb136ab84c9657fee459043ee9f42aafec89e8ba5fd1cc5c4495a41e80590ce197e12c087ff7e6ea88ed798735f55a1634562b82f8514488ada526e5dc10700058980885000e266cad55948d1e080f6343f84b12a3698d9ad5427fad4017d931df77ed2e45e2fb8380b7fa39\nA = 6a9833d768a22ea46aab1a1619f30283a1ec254a2de5652981d73146aabe31041ed04d271c6f2e5e2d090cd615518a06563a94ee2b12cf9f142de3f15599998a712974d0ce9b122a2aa65bf8750f54c6324f12e321a888154330f0f9e1e5b7999acd70d4e6da95c2df1da2d19544b7abd2bd3041e3228c7cdba44f7d1cbfbcf968f8fe87fab523eede0485efaf5cc9e56095cec8983\nB = 11e782e2b3f469b1e3d14ccd1b8301ffcde7e371f6e9afc99af5809110c6d70e1cca5c0bbfeb95fc3ef8352581c11ba75c0f8c445ce2aea903769a24289581c95ae5ebd9553fee61a30d155bf6011278807833eb2ce7ee2a98fececa23fabaaa259409e88e3c4f4eb1e04176d44878ad3f6961e0615ade2fe86b6eb02adeaa7c9019d63231a28f84b7dcc8bb0e71e2a717db09301e1dca20f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7cd49d72bcf5ff4fa2c686f21e1f0146c4f24b9ad2e900dca1c0a5d2fac5047509064e65ac582946b251a3f04850c9abd8b80c92af0fb11ac13debdae8b94927f1de0e4bb217e78f5d04897c6a0762667d3d883cb754dc610442c9dbd44228a7ae4f14fca145550d813655befe3bfeb52f1c76f989ea8a1dd9c10fbc7e9d6574\nA = 109fe33568598972063279b71ba0efdc2e03f770cdec331428fb8ca084c9b20d0fdb5cf9ad7ce90c8cb8f0fef10d219d7dfcc6b4599440db8cff9971da7852880bf004266886eced8763b3569720df3a1fb0dde2717ce0183f2250034871146628430f206c12f5fd87574c206b203d90c0f2c705cad3484c73da8bf4e9f7e1bd433a6f7fd27df63079d30c490aed7161bc594eefad4bc0\nB = -b95da952cabdebe0194b7fba519768e1b56149353cd12023b97397b59e0d7f4dd1d27b65b833948f58e66d3f6928cc3140cced835dbd612cc82a7e9fae1621986f71ddb6707ad57926b03e87e165d30fb145795a70627975bbf9d9ac9bce07492de5227c666663cc28b3e70b19dbaba7f16849535ce5fd61e91cd2875e0a534a10c60d21f919d566a3469d108a35ec3f023210efd5d318c7210\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 98a89cb3c9602fe503c32c44609bd4487b6c8323737b3376dafacc3eff96efcce7a31f1b61ee6799dc9561e77ac058fe5195cc013e72a2864f7e492d9f35244b321d46270a582f6f14f15fa8203d392e81b183a1d64d48b51d70e38d49c93869ffb9d7509f15ccde547d2d9c4dccd50eba49190b6e831a9f4f9000a95dc83f3c\nA = -67d7fc8f1766c40bd476cdb65d4dd161c3d4c2c5860a0c559f0e87ada213c9ed33308c36bb1c7d615fa69ec53656bbae6b57181a0134af23ea2a75f8fed3290a2f483392a3745fb57adf2121738c84f6d34325121a702c8ccac0090ea27fe9a5ebb6ba9d4f397e4a7e3151850b3d7d25643398bd3e4c1da081471389799245d986cab825a2e6ca72b38ff978a2753c835299ab4597bc65fc\nB = 676ddc4d18960817ff8fd2adffaa68c87d234d62d445d6ba3847ded849356d929d9e4ff01f517d7b1c0778bf90f475923517d855956f17ece1e032e2fd474d2133d6b8a591995454d8b587cb4f6fdd0fa29305f146d340cbe6b6efd28a926c73735621be0c5decb792083b3f063a43dd9f635e03f78c1bb56389a5cc993c8f36134d755a324d4fccc2ac3bafa270df67db0a4ee6ea4497aa33b5a8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 76c31404854006a7d55554762094df6e11e0393f5b0451d85de2e5b104432df72023a35f44da10dbde01cebf77b8f9d3ad582373c5d32232564729af0d03c5450e439045d96a2f0a38871c922af2bd38c545d219adce0ec80fccd121d6a733bac09253604a8a0b1ecf0f24e44b818ab9e9974181cef10e9eb17684c57d72257c\nA = -134e8784878a8f3cf49ccb952075f9f9bcd24a20f8883955f262867045c11a9c566abee00638927e5de924872fb98f6376e321ebf3f567db6cfeede62e04f839617d78b7c9d3487b60a0d3897b3fa49b14c12511d04854bde4a9dbe5f31424a3d05cb75d23b46f6c0819536020880afa5a2c173f6881754b56f82a2864c99c820156f96b5cc4665d603597331d98d90a52f4a30c6215ee5eaa2\nB = -3c5c0d35de5fb21c84d2db228829f43b31132b582556b92b495f59df5", - "02a6d00584bb5bacd9b8c1a8c7eab91db0ea24b40f07e62a712842d5c2e1d208a6412a068cd5c6394d715260b67fbc03e3ae7eb4862f74f4d7484f747774fff03830c65fe022d579adb6737f6dfe297db750e6a58d1004e7e2716838befc2ea97179ecd53b7f36e3540e1c3a0f3e044bfe2d0efa9b89d2d308cbd0bd88ab3706\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5b704b3181e5d0494937b4d6aa8172eea82919fd1d884493197a6a85ff047a7bcd5dcf072bdcef0287be20d4ac49918d1df550d184f86d7220f0a84fc4da3ad05e131c443fb529df01fec9fe4fa6fa2f36e791f9e16b4092759016d2f9b1ae7c3d071c57edf26386aaead767a3109c12a5004c7b9fa595e6d592daaa2dd1df04\nA = 48a0ccd2d14e14e2aa862d306501efe5de239e8ef36ff6251c861a0aee9f739411f402491bd99aebacdc26c4f30306f9137ffe4579c2f13efa81b979ddfffcd23675ac6307c0aa3ba8ee77a2e3a3c8e241bd2ade6484e6ead32ce8d752fb3584d14688f223758c5cb8705cea9c56136b219d87f9904bb56be2ea1c9a035df33455206e6b7972cba32ca4c3db41991117d88da3521780fe65c4023\nB = 160120a35ae3edac3edbede9ff1c6f317d95481227d87785b7ee46cfb80fac9973e418244884caca3211a3f6cd3bb419cf70fbc22d82ba5ab98ad80e1f6c2cda753aaf7be78613ef25577107a47ad1ee3c3645db85c4d29bd77900e99e1f439cb23c6c68662c05322f94feffcd9e37d8665cde984387093a043447de590e7874e6acfa37ed302040df4d5c3dcdf9fed91b3d17ab5c141d4494d0f301b508\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 448c3a64958b82ccaaed3c74706ce0a48c5e059c3610cc03a6b5a03a7de5d4f1d1e4b08a31478fa8edd58401f0171697f0662146ce2b371e335d695f9e4a671255f29fc0b9b7d1b2eca4cc7f8357aa0920b5942e31bcfae84e909828fbe5d02251ddf10dbe4c15351f675e96e2eae6d044da1f0858ce8ba9b7aa146850b85d93\nA = 1b2a52aefe44170376df29d17ae2dc1501c9c296f72f271c21f53db71247e72c3eb2b780190c45343bcc8f548507559ced3bd4a6fb13f9174dbddf965b9c4a56c3d88727736d78be9db2268cd02382e50c6fa28ddaf8eab9f44ad45d5882a5100b3027c150a7f3bb36f29d24a76e40f3820ba116d645800459f06c20679321cf5be72450879462f0eac99ab6ff8d26b464cd0e6d78621c9263394c15\nB = -b7d9bd08d7d8e0e9596851b7e03c78973a502afcc7b5fe5b0db6034ebb8a11df1ef7ed0ae1371eb4111cefd61c61935d768be3e3755e481daced219874cdf0d07a76e7144be626cf1fc21c8a0e9db4389ee213193775e95d4d86741d8d8fc820c239b7a90937000dc3e89b2fcd61b44e1c38c655bb3d31aa7e422b4406c9e4a88e6a2c18ec7c048f4a6b5b270c90d9fb378f64be3b5b351621db48a6c18625\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2192157490ae044a26c23eea6da51d3a3dd08c7fb67a9beb76d37ee24ac0089863aa7f00849b81bab8259f3a0e1bc744d841e07aa413c286e4bef2ff3356bdbecee756026915894584b4fcef7e49da4012cd9fcb5dbe3f3b867cb6a7ee959a328b0fd56a9eac1f4e40a22bf0a30073cd2d48f99245ac03c373810c54eaf3306c\nA = -598eef47b40d1fa1ce260edc561bd1c1ab286a7e068af412ec2baaecd07c5b9cd596505ea1bf0370ea961c4ceeb9be76baec74e6952cb846f20e5da406bd01368b85d59569b403b7a305cd7448f331f10a34def43c738fd633df9a3eb194c32d53aeb567889927271d71d3929d43fb9338248b64f7d23cd1b053239e09cc2ccf5fe9c9ce240f1a10fb151a8583e4b4cbc70ec3082dd20a9962d564544e\nB = 559fc917de34bd7dd7a23a432142ed79e3ac4a6caa357eea21e423eb9af7fd94f1eca735d2588ec4c2ff013520c3a0e209627217cc69bd5a07ca46a43ec1f1bdbee5f09ceb1b2c18bd388d3852e51070943f16152a73da624be680c671057677356c6f281a4ba1f7c60609125d7fd9086c907ca5c191820d80e483886b70c1074e2963c49996ee92577334881edafd88270bb967da795aa4fefb739e4367390ae\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3488bf00f67b852592922fbae64fa56d2e4e7081678e789bbb3b4f48df62576d537da2e99c9bdd721c725b9a828194662bbd51ee20ba73d4ed5562482540880686d9fb1e8ae62d08e39fdbbab1d18e399ebf07b3a6559dda8b043fc25a8152858d39b10ff64776e00a839950e7a9ed5ea95b594b6e9e9d4348ceae08071ec5d9\nA = -1b135d8cec9969561be396323e2f8be0c60903ca59b6c418cb19876e9e3cdcb9ce4f5251eadea11fd6e785476c70822aebdc94617063d161ebe55584a8a774ab230b8228a2b65bd5a6c873bb6b261429eefdc7d0c64c7e78133e739efe57f835ad03ef8f84601e1a2310659db5e0ee706f23e3c5c38c9f8c36e5b15b654d1cc528f1dd392f1b08921af8be6fe4e4e6db774392441883ef867bc729338943b\nB = -34fb63435c90018e5843098e379c76ef3ba0615b6b500854b3dda3e77fc5646228fcf3a6e1cd87a506e4959ab05e24474990ad98ad0865942737734c03dc289307f1b1f424b9a8c2264350943449b3d2b0f71f989039131e23095d122ae98c0089a184dc530669e804140134e5b602861a5e61c030fc3d3b3eef0a59f8c0579fc9b0afceaf16698de3fa07c43231312254c04ab11ad7a29efc4597780c2cd1b64b43\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8ea5fcf7fd41803606c95729d2d910941e43b222f9b0c93a1a803b197fababbd653a92ee34e805906fde29b307a962a294aa4dabebf0d181c046653ad0fe6da1295eef817f3289dcc6579cee8869198c39a9f79992cf6894162d35d812df327a64470c935994aca4985d0e6a783b853ad762338dabd575ca71034e29d768d014\nA = 6858d029a62b0f75e4c59f3ec067e3990b2304c90a097daccaf554abec49a9d297ca14648471dba08f22ebbf8e238c89ea06f188203599aba56611eb3d4df09ea795a7e28f91f4a9a582c6b949c6ffc584a076de653446aff9b24e87202037974aede37aa9a121b5b70a3e9b5ca376c9056c2c91f5d5484baebb64cccb6a09b4f40529afad1ed64b4cc4aca586892693fb5f92edb6b4d5f678f7a2441e51410\nB = 197d6deff7adc30b025e7e418cca0a641e1a1b35f78fb56b9d8847f0690313475e6fbc6f73c3a718b10bf37434dd9fb1eca33a99bbba674195b20d35e3b34ba9d7c8438eede24ebb48e6d39eecd93fcd7dac44235ad32f208919f57b261da70ca378f9b03ae5e5a733f97f0b3f4102d971272015bf50b6f3e50c7b36cdaa14a8a580366c9cb0118ceec6e627827b0b8f614656292675ddb66e1c55355d5a1d78e69ed31\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a25db977e7a8fa4578fc530995335411432ced67e131fee2cd7ff56970df64a6f0f4a7d225d2f4ccec8e98273ec9a0f1aef01dc0b866e425d64e09cafb9ebe3f80bc0ad71c769f1ecd5efdb4a990ebd3a94303f52f4a97e3a1d615918f8b2df5321c4aa9339b4453d7a710a803106dd0ab49c6cd9aea431f97fea9fcae0bbd90\nA = 13f97ba15ce46ae32147a0aa4c1639b6b555f4d8a1af15ede4f1103f7a0b06b4625bf456d667720adca0c4e26e858f008b012fae63cd89322b33fe51e87714519e7dc3cceea27d968b46ebc04024d063b17901a7ae978591ca6ca41afffd81769f04b714134cfaa6700cf23bfda6ce67313988bba5fd3782bc62f76cf551d140c978dc002a779ae37400d34cbea013a5d1338b203ff267861edd88ab8ee1e4c4d8\nB = -88d8a4c8c680fb01f493f73753c70ee753951d4734627da14962e36449db5490b8c575729fafbd203a125b500b96364e6799d9cfcf0efb4ec877e86865eea5e99e2fe5e7655c1ee0eac641e73b71c66d7a72c2934d1ccfefcf59781035b2c7b89e5de3f7d1e9128cac57947d22e7577832ba374492a2f53be37e17733d8bc625fa77fa5cf093975049a5c477f792fe75e85da26cceec820c8b255df0292824b4c3a8ed455\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c1f2165a402fe9becea284dae60453965ce327f540bb8969562485fd1bb60372b8689d9c9c97c91bcfd699dc370117ea8b704f06cae3d972dc6e5eaac971597c69d4dc24a68b256f97229e643706aa6d2d844078a5fee2d08270820055ea58155d7bc754f09d0c6f804e55ebe53e3ec418747d4130cec68533f6f0c2f8fd2409\nA = -626a1580e52ba52a877cdcd62b34cbc7f949148671d4a61201e03e98985d704b2975b9a2d9c4557deae065becd662ce8448171ac582894bfa2c59d4ed20c6d0471fcad1d0fed1291df5e4556aba72f3645486580c8bfd0e3c8f6cb34fe17ccdd75fad4d4a2db4e00bb8c2a23ed17a31e95631320590f40416c153efdaf897e3b278a1faf1917554d9292f90c4edd5992748b58492289eecde1af34976ea8ff507fb9\nB = 44c336d77391", - "18340048939d6c198f73f90e13030b69be286ef920902391d87a58df3632091d0ef25340eab395203e8dcf3389e95debb7432165147e145735d2e3226637b4b8cb7d85d68308be07f217f57fe439b31fddf3fd469869a20f1f852e1645b0d4903432ecd1fb6397db4c11f6b6b9c0fd25778b0ff00bab9ff576b16538a6b7da40f01fa7b987af8ead41ecb66b8940c0e8a1208d0026773e711153d99348e92303\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 98eaf476f11168bb63fddf7dbf3347e619f9b580ea6804ab893214e94ebc089cb652e307f1f37ea7ab9052a352e260ff7d1e8c17461bae68c52a8a8f1a57a84c79b2c8fcc2d504ac4f553d2534f2a776ca129ec1942d83c8ae24c772f6a8429bd61949ca1aa714cc3881ed731497b84415c88ad4b9be34197a549737edcfeac8\nA = -15897a5a986641fc2cda42d185d72aa1552eb92f788bb71cc74c0e424bd038e02c620d0686ff88ebdf0bc1632093c0d89e724e7d5b526b0ddc4c7e145aa90b36be0d8574901fdf286df84a6b52674a78cf21ae4865618b4347bd905461d878537b33cc41710ddb290964c48e44d4d2ce2ed82847de75938d23ed418bb9ff1caa03b5c1ac5d65692dd1defbc6013b3270c4314a45dc67883762fda5509b915e8277c1924\nB = -3a7141f54a0bcef68cbc3006166f7e15a5c2394892a428fa417a485981316a537cb3ec757d4a2473fdec2cd61010a9ff865852af8f43afc79a97d394bb6c58643858e2b4dc5cb958c33781b5c35aced7882e8b8d7b4e4249c2b82150adfb0c8f2bbb1cff3d2ea27ed24eae030ef468ae4d6b7462f0b072cd2a2f02426b3290b87b14d14b34e91a94c5bd69e9eda53335cdfa7df90a57f97f3d023ff85537fe0a8bc5d8fd7901722\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 34464b7a50713d17b01b5940b5acfaa7006aa6b9b083bc17e0535b08783761391eaca8703af2edbe13dd0fe9036d38aecfd9faae08c0861042ea1a25b41fa8a15b7721909783de3aca127e955e177987518dd010306a795bb66466fccd55bd9e2bde17470cbd36b1e8f8b63805229754387a5fb40f3ee9a8afb2e51e25c8bea\nA = 701ae8c5bafab7f41c999e492f04a7626b2b1054e6dce1b83002b2d3de46717225b018733b0fa8fe3f973202da8a090ae3fd14f48b27097513ecd4ceb1b9729e7783c17fee9be5221fce4ed3860275b3b36b7416594d2b65e198ff564e82301cae23756c878494e57b5ea8fd22ad800a582cae32fbc985d122cbc6e0eac77c1000d3ede45ae7aa087534adfdea8e9f924efa1b19c43dfd3b7bc83d7c40df7c6578a320a19\nB = 18e0256543619a750384d30b6a7afbbcbdcd9a2ce644dbfc97a8ff699e118032558f706502c9b956695cb25a46d7526596b3d0b67b69611009265838bec533a9488d24583e7d7f2284e23c3cc4ccc5920fc57e24f60da0d479d41f5b9c6ad9152903a4f37842176c6257fb1e3e0681d6d583e704c1d1b24cf616fe638106638fe9d79a0c74f0df67cb2df9d99185324ebb037d01ba0066ba947d5345cd3201b19769d438c43292f572\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bc57cbb3e1051d3a3035f77c2e375c7e3221dd472edb1a5ccaa7521849fc0ccc7568238aea9335a733d839e89ace6f2b66ef238267e0050c065c3d9553cf50cc5cd93d34fb43c3ea1c31b8ebf0b751f595a7e5e3e860b366229de4286b9d3f0267f78c6888ab3f208c55d9292079116ea0eb9f4ec2934c97149aa132c03336ea\nA = 1ffb0aac11f6d1d257ef7aa997a030e2a12b0615fb11ff04f344f6ecd550e8e77e9883c246e009af33a51204e4066ed4249950e022a61337848dae17c88317e15ade5b5499c0d7597a69a02b6c18db0f975c19c16d2167c583571e947676ae9c15be60e69d76e78329aed5fa57dc5e616795b5487f3d52bfe74b54bbf93ceda093c2e14104a6d2f017f0d200a9fc89deaa283e04b0bd9015ec67598425312868eeefeae9c996\nB = -9de2d82e25b449b8ca4b02b2d2fc0a023fc5804ea553aa84674a815bd74193a2e549070e2cfa0b90a53070646875282fdf855940905f834f5a07f073093c658cd1813fc5cd7092af592092d789ab5481bfb14b6683139646cff8eb1c5dcdb6a33113d1c97d4b587f15f972c06046730b7e712a8e3dd5f4bfd07cfae289047de31776f222d11510ab6b70a200ceeb6802d6c33f913c509b31b96e2b8dba9e25b0d2250c3b102d814683f1\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9f7f4e010370ec1d76fa83f73c80825c3b71521855fca5db06d7ed830c910d0430375bf319671f6a83bf6b57d9d53cfaaed5bc5d615c5690df0067b18791c33cb9f0ac9fa5f0473e4f4eb7840b0b660962097606b3de5744089ffb37d9c0df1123a91a5896d4deeab8aebec469b099a3a9a4f6d822030ec2fc4d11636706fd0d\nA = -7f56093243ec2399548ed95df79363e6ff09de211dfffc314b7cee526535def0f9a8eb9aa6f1736528ee7aae8be55c06645708d576111766ea33e0564c12103edd61ede3128a7a642f968eefd0d7f3768b1325c2dd910d459b15e54145a234225fd29932234e59d3ff5099ec4d5b5c6075f56382ade1101115c7b94e1e2a7bf075dec210fdaf2357c735416dd5d616335002d1cde6056bf7c478f810b78c661a3dbe6e54084bc9\nB = 4df1a6296428d06f51f31a1b0f66d0b77a04db3bb8e1b80d64da649899a1a55d4041bf0bb47d3e3936ee0f3740e1e8c2b235e1b8944d28c7d617d1f968abcde9dce10d6e3c27b2e3607d8df815f5a39da9b5569e95eee1fe5532c0a80011e7415800d8a9ec175fb1d13dad959becf04964b70dabde6d37072dc9f6d914309b850cda33a565515dd6c0181fc48bc7033b314ae0bd5872480e02ffc08dac4e3030d83b33488cf149e19b0021b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6da5fcea305cc6eb47fb17190889e6a39c339da1bea2d7c95e997fc538b4aeec8b0edf7c109faad7fb6c656420f4afa104ada7a0d3d14d3ef0fc6774b59aa2687c0b4efe7c3fc83194a89c832f7168346cadc2b1fa6fa9a23a67c91ad731b4cfb9943738c7f9951945b2eabb3743473d9c0444ade756291f53fc7641501597a2\nA = -19dfb98f9f7d20fd331ea749d2019d8367935fb75ecde45d6dabc815ab9e593e51178a72816f85aa678304e6ff3a2c24079a59aca253d76c4ac633fea1070753ce770765bce47428f8f5ae40c26a3ac91ddb551b3d575bad9a3b6fc7954acc93aad2131b78fd212fb0db7cca4195b41651a5311bbd4d8c64f1c93e6520eef8e6308e98caa1cd0d3c9b4041182cbfa131c4948257f1200b1c5351bee77ac8bc8e44680ce64ed0648f3\nB = -2736d5038c60553927f389c0650bb1355b0ce745a7dc5f52c9909039465344af910a5f6a9cc4ec130b9877c1cbb52fc08b20d672e42b853d26a02bc07eabb9e3f91399db8465b6a8b1c9f4a4b9eeeec6e9b6180f1a770c139c8f29ceced61cc7ba182884ae01d14dd85bc924391333e8ef039b586b6a0ae18db3570aa560c2b0226d5e23e7e753873637c25aeb19e74997da4f5d0755571785bebbc7dade57446e0df4cdb8df23c1003533f60a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c0265805aa8ab52da5aec06ef7cad2026fa0b18edb27b4903e3c068ca6464465e34d3f3bdb4bcc10a19441040deaf5569645f7e09b36c56631b3a6144d6206d39c9bcac53b54210db6d484cd6a2780bc68c07272de03a9bba7e51c9d86cc8883cd2e1864a2ed711d505930143c883c57545e9c40851c6df8b3314a8c9a0d201c\nA = 5622f906b077d243521325be82a43fce321412bdab1f15e4ff0c11a7066a288b7939afc01d30243c8a4150e74286611ac1ca4daf457aa23508a7af869d2d55f54f2746afaec477cd7df0d5711dd636802ae7f673b3f730236ac3899330f89cb71d48c2838322fe856d9d8b4053d9c1e66acdb5e43614ecff954dbe37c5269d7ffe00b34e682c0be3d7cf653ef212daa3d55dff92b329126636e440b0bab55f4810a2849f77c39ebb93e\nB = 1ebe0d1800b1fcfb67d7d54568e45dc604450c1dbe103ee21d48dda300c1d9b9415dcd9f5a56cf12c2ede3c862e895efb83621435377387b29b882b2acac78386895c7daa90810092bd3062a3a4867f92d54622d7f0b89b40fabc4709fd507d4002ca80de231596630c234fa418611ede0ae4a9616d570232c1b03329bad02220ef64e455c164aadc16190ce35b78060a6b117b4b0641fa64dd8e8cddb5914e7657573804e63dc7b216b1a9aa175c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 606d2b6f756548568013bdaba6e811dbae88fb01f5f36d30d15dc1e099d86bdca9fc1eb3a785034ea14cb7f4776586327d57ca5a52ea1b30f26e2a76140bbb0e930c7780673770fe22c5ed443c349510e1494ebe402f2621b1e6bde39b8691edbe5c7242efaa6634553e6af146dd40666edf4a3db5d1e7f9347fa1189c1e5168\nA = 14ea5e6fd612945c71fdb17ec44d95015773edc908a85a6645a8eb823", - "d11226545d05b81791401cefc81ce9765eacea7a619cb482f29d38988d355ce731bc9009969b7487a3acca2d2065c1faadc5d6dd8ca1dcd3f3d4ff61d0a75ef75272e62193618f6b802f70795041de26d6ce367ba996dfb91167cb1fa16c8977f982e1718de7d60275a7f66e4ad72ee55ea06267cc4e8b08f488579825cc674b0bdfd34a01bed08b62004fda15b7c\nB = -8a542280f6c8bf4d9fbc96d5bfa6ee0d16a09dffdcbfeaa2dfa1097a760dec7bc540a0b5b2020bab1eaa594117a40a9bb99c3f16fc340c262b29909608740b8e77fe4706a88dc0fc3bcd47998e88fa02f617062393978ac1bfe14235d43f3d5edbdfb9f140412f4fc2dfc05a700f47b1f0f90da7ae07ae781d9ccdbb951f19a8b8a9a7dd8a65942842cf207f3baed3a0b2f08a06ad0d9ab7ad0110346293d51ec53ff8165b925c0e7906be8b7303252\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 512220042f151479a6a8b7c743ba83366cb7733caf37164e9c823422ccbf78b0b83f426a7230f559d50bb0ed3d9486c6a6e25f4cf96c4fdcb2c861566c6a73215b6d08995a14569710cf9e54abded1d77fc7722d06fda4557a3a99862e5ce963e1be25336fb42a4629391cde3aacd47ea5f5426e7185c5df27d9136a6df26f54\nA = -4d108217b778694931088bc255d1f69cf8f5a14252156163f948ae58d58f2ed54f518177d668e795474952c930052c1bcfcae11bcd15af168ec2e881e6ddc8de257d0cff90ff3ad409bb3a080d30fdfda99078cc3ad8302a4bdd77de66ac082b40fddb3cb36c75a86bacaf60984a74a0fd575d751ed2830650d85844aba9e3f781b2dc6b515bdb8d9459b083e1aa653ef177de76282e86c99e97dae9c0b050c9e6456a051e7d99adad7be4e4\nB = 7b9079504c635655a588ac360955fceb10cdea5f3de548ca2db681da38c17a70df5798f72cf18691d14a5f400ac69fbb47e64115cf071466c54bc7077a228249209542683ba57791352ef3409f6a947865d8f234ea9d39491b5c001685487b32130bce9aeade97d9537afe3f2f87e8f3315619ef7f215a73cb724f1adca99b90912aeecdc81485c0d00a74387ea99c965118fc6a9af1163e60d1ee6a1eeb12d7c2bb9a54f747a415beb5873d616fa0eafa\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = e36899d83a143c82e19e11494ba18478c0a9497fc89fd83df38adcb6b33918645a416626409a156899c6583ab9a4426438d9c32cac54b78df579cb7b6b1feb3f39ca4a6183743a4b823082896a89f9f1722be842cb2d2ceb605f84a9f9b61cdc7e184593fc2f9ff2994fe6cc4860d255809d04ab47e154eaec9ecc807ceb298\nA = -1422272d9e91a14b38b3e81cbd9411a0cafca23addf4f33c94a1bca70603db879dd8a9c0b95f5986bcb447731219c4f9b32a1e3253b027b7963ce40279dbf4008e526adc0bd7bcb2b533392a105c6e8e1bddfdd2bde7dfa0d2e3b1c6ffa07fea07ecdb9fc828283e93b0ce4861945562478b1a56de32251b7d31f9a2309488f7cbdcc38cd6b1c951570675ef0d61e1df69fed78979dc755f160d93ab5a3e65dc2944d3333cb85aaf87a153a90fa\nB = -2424fc1e71286ce3be684a10dd885e4891b52e9009c3021d90ebcaf68b6db81130bdbb74869cbf142e0f44ae72684fc12c85abb5157987428c7812889beecfd7bb43fcac2eb6298ebf1dbcd2e70e4274841c2703b8685df18f6e5bbaa1422004797defc6ba843e77f891bbb46699a863bc1d77c5e3cab809c247e2975e8170da00fd9c8b232abc3fc6b16951ac4e6c96f9503c1ff2d6832ff9c35b2c8aa408645849c577d2b8599ef520da57fe2a9eccfcba6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4e8a59476d47ee2cd0217bae2981cf25a2c38e5f5d5c30c2d8bf95856a6e8f42429e565f1836365e550d85207246514624e7ed932d6f5802a50ff9f15d500dd84b27729c1717a3df0f2d6dfd40f0094208445193ba6500ba03fa3f4bdeaf9251aace8729b32ec3215bcfa170575e26265fe523cf44a071470e3b1547901e9227\nA = 452cfc78cb9597e67aacd4ec83e5b473ab8b7a1dcb6097fab37e25d5a6e25c69c73a6c20de0e2a744375bbfe7f612036e69c7a503255d9e17c6ec1dc6cc6f634d4c79bed4764496e5c7c026fdf9408242d3b234195e67a5681e7d7b861f58eb631ddb9aeeb0e5b3ff7a7657a7fde5975b8a9e1f643893bac47debf7918c7ef8f6d7439320dccaf63b80ec9761559078baa8e35d98fb9dc242ba83536eef7ba9901395ef02b19990d8312203df7dc1\nB = 1dc222e7a737e6d97a703fa232defc6c0a4fb2bafd247c8e547b9c474421cacb7692ec98f94be19a5e40269e1f5713d06a6d081a943dbc667bc867e481b99c55e437061cd44c4482649faf870d9347e0252ba9dbe116fb4992dc2c2a0583c1351e9e01e71e9324f5fa942322485bca93c2d95cf304028e68224fed446966073ec7326c93ae326a7a533a36e053437910418bf1761abd9c4c5ab7e6f538e9bf963903e6c80f21a0a38a683e8166e4626a8d8b743f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a4d5e9fb7f0d75ce41ffecacd2ee1e4d15f82dfd4decf5ab1bee75fb97792d0d574fee60a30b15af80bd38e6a25b1821e61628dbe456e39fea3f8a9ee6ef3d2332412be1500fada0c1728a1457656eb3e9d94c64fb2d0ac89f10f2b9ff57d73207274ae7e8c7538936cb7241615b830cc9011d4363ef88f51c7b3ed503c25179\nA = 13eeef030b3110451fcb1a258434aeb51d3dc805b38c72ef7c79d4b0e18d600e5dd28b552b59f3dda1898367ec7da5dc6d9089a585cf52002eaf8f9ec64b8d3ec50d0bef7dc3faf203c48583ec89757cfeaf888ec4a91470a6b8ec9f26a6b07f3311b4fe972cac2f2ffe47f5c11d2dca87c62680e2229120cba4de9cfce9f7f5c33af8398c07ffabac1675de1845e05a32536329647214e54e5d9216fc0cbf2730898eae19e425688bf184d16bd1d655\nB = -ea324da99252edb03f40100e528d9a5080c43be97fe4b7e03d9563ba48040d328e57d0defd4b7ffa9bef3ca0d2682aefd2a0ffca8566e755b11f2e3c6c1b707f1b9465592aba6181e583babd5c70588e7123361a8ae77d8c398e33f894ee288babea1d7eb63e2f3de469e502b5048417043c5a9a9a3eb921cea1533162e3ce9c79e6caf62bbe7e17b180b72c59b9ef5fe1a001b733d909a8278029fb4a63077ef9b3545f1159ad73dd75030aad599ea4884677e01f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2f096fb8fe2156c41ab695956f13f0fd9a084f87ea5f5b1acb6b60c62617b8d7079f4b072223ba18cde474af3942599fe070ddb0ac1a99f42b9506a2648e1b8f6106015aba0bf7a824842403bd3f4ac8b6fc4a9861bf0e8ac59be0322f0495e4b515fd579dfef273160ddf96e453f4ab663e703609c709fb1f016ca919fb26c\nA = -4212bf679cc00adb2ca502604b71dd5dab99cdfaf55ae92aee6bcf8b3b6354a384656c09eec6175a95c8cb4591ce118e783d6344525c25e5b356e45802ea3ce1fe764833132e6b7bec434e4481c9cc2986904988bd8da7dc2e31cdc481fd0e359674bbff524124bab1ba4379885a6cfc1b73d953e6d1aa1b938129d74fac9dc597c31383f2f7e02fd995f7065290a9812ba8e205316ad5bac6fc65c6c7310f1a6b033503ebfe85bf6d3851bea1b65b9c15\nB = 7ad83f97f40d5be508cb394c128764532f0aee9a108eb02840ca1c635860b6d751d5f676e8670e2f61466397e1bc68f97ea52d64b335d07aed22f20bb1ed19e3e42e4205d650e6d37714c2f80d39b111577725e3bc7ce75bd7ed5e44f8377d5fc2b97f05c3c1ed5ca1ec90ba3ff7935a25a8acbcb15fe1fc7aeaa1e444cc2f06c1e6711721d24b8969d465e4958cb87924b3e0fe99ccb371009b5b15747bf6dd5d0fb73b8fdf58d955c8773a55424a34c741406f6f904\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 909626a69c803e9acdca97c56781eb672d6fb31430a53b853f467ca26d4ae96c182d71c0212894b776c88e773acbe9602e3ca56584c39b5947724290def7dbf04c6853a108c1282def95dbd5bdc015b68daeea0ee959b35bc5af98a4ae4cc7486e627bc9432bd009b21ee9af3085f074a3ae1bca879e321018e991e7898f2897\nA = -14eb8e28dd04a159c576eb10578c24fad9eedd3d8b7560b681002a54a4bce2167de05cd061338f63c50b86327a79595a2dbfc1d3f4e76aabaf88cfedb69faf5148c61f8cfb2130511a3bf4a17d846ededd4c08f3b635182dff1854e8c4c48007af028e06f01235fc2becdb32adcb9e2058dcf8f8655624bed9915faa06be972282cfbf8530bc0cf2de5b2057df32e4a6cbc3c772feea0a511cfe3408a6dab0e2714fc4cf15602ba0da03bf0016f1f3f5ddfe1\nB = -388da160568aef9f82fc16f48a22e8d7aeac99121cfac9b748c815e5d3a823b673ddcd20c1168f98ba204df5e52535f61b224fc0374092f8c834321949fa0a812b5e65c492fd9fe8246b74143a943bcdbeba16024e311d673357a3dd3eaef9ae3a72bb06e03e34e091cbe5b6a9eb9fa3d7f36c03baa5c3e242f2c186b58db5dddbd73f6aa54aae027529b8f8f0a536b9b283ab08247b9977a2ac2d0d9f162ad03a2fe247d2c589b1a2d14b5f90d5b9c0a95918ea956e261b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656", - "b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 128e8844a2f04704a4a60cd33e85cb7ad373ff683abd167894a35a1daf947f504c0abd7a614e293ce10797a5330147c88c4d5e1dad1bdbeaf74095e3f5a515f2af68b7bc11ee1f53b493133905b654318dcfe73118ef1931eac47deb6c4958406b704ce027d9b027803eb8e639b52d5983094b8ff4b54e86a7dc6ea169ff1af4\nA = 75e6b045aa44dd9b8f4b434dd4bb1346fcf558a5e96b00fef9b6cfaca72fe8b1672edc2a64beee8b959683b1861138b297629b44a0caec6bad2ac05665728379cffaf66a129f0ba40aab7c6b1c3fbdabaabc87ed3dd580ba80ec7ee765e9a8fbe845c0d207eee7a1a3a0c39650c75ccb6bcdae2e0d5149991dc3bf899ae9b7626a2baa17b168b260d82fba84a12f10e09234035e08b730cfc230f0d2651c03e34d4952fca6409b5c6ea5d8791c90466bdc4adf2\nB = 102fc193633b0e60a48dcc17aa76f3e52cbbd1012f179736a0ba7a102f8dfadaf434063b0ed1b1528a018b349eaf192fe62f868b538cddd7e8e6fd98b93147727d58561517b2836e4a373bb31fc8d5e42d16126ed80b880c1a37940c138fc1f7255ee0b7fd39b1b799c34e5178580cdc076ef3fbff65fdff7497398fb1cac75e5c09cc7df1168a20f88a16e7b3ac78091a90f1169bccd48c0d06b4707ab79b741a168deae5ced5d48bb5f5dd3f465e43c82b9db7edab24569b2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9aa9699d1e5d2c6acb21e31890c1899f30a925b834adb5b8bc8cce83a1718944a2c90faa71b34379a21340457478c0c43121dbd65d62e290eda2ba6230bce4e6f18555a1380c7c95c1700793157f7c1cbabeb09460ca28dc596bb17851ab2ba6dc6bf311ea69bdb7fa8eb78df74adf171d4677a154b8536f8104d919bdd58648\nA = 157fb9e1b38f288db78a1a0e22fdd9f48a59779487a9ada2774a094d34536b85993e7b9ab6e24f081c4cdfb64a82271100a054169e4f1c24e3957ae9aa8300e85eb2a45a6d5987eed4f0fba6fe8557cbf6128e018c5f9df028131bbba6c544b2c6312aeddc71405f0e4ce648fbab9e5d51685949408e4ccbe06fe501a36fc13ee65c31f062313135054b7679eef45964c77f5a1556ac09b11c496d0ba8c6057e283bdaebb4e6d9e5c557d975745f9f98a288d5bbe4\nB = -82cb6334479bd997c771e894cac1ead87dcbaf8f5006be5c70ad48ef94303137bdc45f261af91a201b276a17d884a56ff27af7dc06cc5b7b9c94f7c4d4a36f68f8d309c477b4969a6e7cd1b2afab9deec06555cb753d8a0eb00965359ef865a84bfa87b815a42b2050e1635d5ae5e3743c007bd79e820aa37a968702a960fafbddecebe63f022553cadd7a4d4fb27b4dcb981e8b490e80bbbf13af8c4412d158775db71f5fbc9986e7b8a8f9299574abf7bdf9ce7544e8c4e85bc\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 46e401989fbcde9d830dc6e3c42768999f153d44d270d4805c5beefb470bc1e82706aa7173b359763c5e15d146eca91a32a36f0a80802871933cc7f2ed15a5472988849a2d2f57543345b531538db57ab9bcbfbe787efb0a82e61baa505aad628df5f9e881dababb35bc2decff267eaed3d3671757ae1764ec5163b792b4db3a\nA = -590c16ea2cf7fa7f63b5cf74804333f22fd2d0e1da7d226da8425abad2b39a4672fcebcf5cc15d220b0ecfeec09665e682fff0140f16889f7a6ade9ec11aae3fa3a369b3fc133babe52e42b7a8bb9a24777521f4d9e0efe7d7977dced9e40784c24d2c6056b3b668ada7856da71af73d2dd33d2e481ddf40999d86a6e236d0d73f31a67c52cc8b38203bb2840c0b92c2612ffe5fdb6be87f9a787d70b3dd506f9a63d144db3417495f0a48523c812d14a89710d95bc6\nB = 5a2865cf2254710a1a51ee3056b0c1f6c5f77d22d7aa8f939e6f48ecec529a169e630c554bbe682a8c4de9ce4daca77a278d7e752cb678141ddefa75ba42e661885a82ab55d699414ffeb75802cb8f4e7583bec8a7ab58803b378bb60fd46f476ea490c9aaba568ec17f3a6afdd6f20ec54a512f7aaf62d2f941e35b4b72dea77095e863dcb38bcaf8777707c1dd437ef2ac6b6a8b2b832f80ad2a6d6f279c053d02058b1a657a1cf5b6b269e15d29087b0cfc0c2d4c3fbf32a167a3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1c9649f4540556ae82ffd71b2c71ea8588aeb845c50dab595db9f8faa01a26c809d30d8433b6c0add465e164cda2b6723c942ee87241eb7baf9944cae08babd8e22a0eaf35c09e9efdfb9f8bfa65d53ee6eb23fcbe1d12a66ae05e7592ed788b231b000f895d098a24febcfa4372d249575926a5faf966072f29a62a401ec51c\nA = -1bc9ae5fc2f6a3f1274584bac1e145f02c5e8c4779f4df15e98dd34344c988c1437ee4428485a09090d81b18606a6ea5c1b9136872ab5b37373fbffbb5b3fa8fbeca1e112b9f1643658c2f38b9548cd8f0f271779ce0acad403177057ea0a2af2e7435109879941fbf463488a2522b831b95c1cff21d2d816d70c25156369dbcf04a0e28e1d746afb8a77713703fefa512816fe73e203bb4c3428efe09b946b750199bd7a03d30feb90230c219a103ad4528cbe0de1e5f6\nB = -39cae179d955049f830867d4115d3bae25127c945b1fa0c16fa850e8fd77c1b3b9b7916b9983c1659b7cee77b7dc72abfff1c56681b7931c5e58cfe4f1bf0168ae32df0df8f652223885717a98f858a497b1a4be62a2215c39316c34451b0d957791f49139921d9ac8041899b8fdd5d3d443547a26ddf5748147e4c3e93f5043ede42f38a9baa628df65d3d6148ac2ce182056700f0f94029be05d3ea3a218b40f65a87b4baf097fce107c080de24880259f1046175db1297016af76d94\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9fcf6a47addfa336557749821a88ccd2573a5ce2c3094a17d9a29b33e043bea165499e89fd2c939f17a670694aff05e9af46836b62c96e597c83681092d63ab9d6e22751aa8fd4b9ea94a90a373876ef0f6514304a495edb5ca1795c9ade7965c70f9aa92f8ea460ccb670e9a62c81e9c\nA = 71b93fbad39b1c2755f2051ff7d532d59c985756410d58aed3947d6ae737ace5aadc35e7e0d29c684b9d4bec9c0fa277996bb30230f70431cb7b905\nB = 167be8381a3392dd4df62e150025e13b388bf366922ba8632614928922cc290772135857d1b5234d51c27862cb1a055c1b86260b6ec\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2ba940fc5165c6c5f7f4cb55cd89d1d5f59e90e78730bd66fb120a814514784879dc43ad4f355030ddb3486a59bc34b601474978a94ddbceafdc0ee23cb18708bdbd824d37cc32577802ac6057fef29a71f168e816309fc80cc46f251e7289c6a57fd222d5868263360af63dd73e7c8b1dd6b3f3b6939849580b9231940a4d\nA = 1220ac4bde4feca135268550ddc79d8b05ff72f483b39f77436f348c4f5360c22c598f7dfb76697bf6d2ae86c68e90748b8b729b25f932b2e5fd33f3b5\nB = -bfee56cd412318cd62e7b6cc49217345d3a94e7fbf6fa19053fa685efbc0f8b320b7e43883189396781c49371dffe7d126c032d1ae4b6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2ba940fc5165c6c5f7bcac0e449b64801e75134a390f120acc58cbee43888f50d07f7aa6dc2b33643c025cf745434d20eb1aeda8fcee5fa3fa5baf10d67c21390297857aa50bbcc4a29a6b10885f97fea60f1b88fc72512c111b938142ee8d67545efe386622162e8fd50418b09769b8c22efe54fdacd652580d609f0528bf\nA = -7bc53f6f2e78628678ebc8e35ae4905caeec61acca5c64fdf595689cf005bde2265cd43172802fc133dafd933d7b48def44256868d202727a4aa6c0cde66\nB = 74147c93e729707111d0d531b1c135453f3e59f63a7e082b43dceb8b16cc5debdb6d7c0ce0c00ec9b5ca51e7673e411c3cab34938124db6a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 43c47d7e319c32a758360dd726a1d91e2cf5c57f73cdf9ad2040e61a9c282a2962d96d300e04288461eb1ed37df19e6b88f104a250f9885898740f6487b081515314e0a217df2d4345d3cf81eabb2bfb346b634b9c251624748f6e9407cb677aff4c53fcf42cc027de267e6ec011e14bc7f3bc6666f693d21\nA = -1e6ce0b44105047d0da0eca7b936980267db41d41319dd5315889fe8fa2329023d7cf54f71ee179b5bfedf442cdad1920d311966f7175cbb953bb42ee105393\nB = -23a330c7e06cdef4b6b121d15a9c0bc774eb5e432e72d04c5f03a0c588e55e010b61f57c03c51edb1211685d8dfd2a35393091fd0e3ad2304fb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed45", - "2d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 768293c84c431b9c8dc6e538ca3f856c60ae5e1aaf42325865418b7bed16c7fc2589968319cf41cb370657c8edc7b969de10e0566b64ec796470b630e22477e7aafb38e99b6012f100c9d23d5517d486e3cab1fc60c1568c0228c9b55d2d77d23b1351fe37ad4fbf9c07f29330a539de4a32709d043dfc9e21aa1a\nA = 6bbaeec78b6a41818b7eec42fa3be7d639dfd86fbace2bc14e0369dba6dd3f04ede8b808743d809f43f70f1146dfdb1d649546441919e27f1f7a9760da4a3b152\nB = 1199dc2f52868a0cf440f6666b576541c7aec1e9cee14c1d22010ab0f53fe8bbf3029c639ff78d89dce82de85fd8eda4e67395d435df60158623c5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2b90afbdafa02ce68d537ae807b4e7f3e05a66b20b84cff309941fc3150f99d083841ddaf6f19f5a76886ad5d853c73051a0457e95eeb0fe3776a084a027ee77d14f3825713a59622ea163a679cff904db33bf6ab23b06eb4b31f4e34fb122c8c170321164439db783e7bec1c265eed33f33bd9cb6d1611c00aa18a9b4b90d\nA = 1c4821515167f7073d4b7cfa318ead1da1131499c12497447846caa84176a9d4af576fe549fd8b0f77bf8dbebf6c395f84dffd40400101bf28b1dda0bbdcc5da255e\nB = -de60cd639044e863c6a49c73213dbc2ca84e4225aefa5f880e829f2d9cb48ae92e3f2680c462ac697dc34da38f65fcdc1b4d8c3c99e8cbe29660b539\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 33e8e8e193b4b99d8bb382c29c1fc5403190d7654f43cd77e28d1bf77bc3a728dde9de9a89c6522ebc7222d25f46833fd1753a44275b04485c77b675d816090280b3541ca61bfa33921a79f7286830131d6eba13acc46cc2c449b3a359f1cb49d67a4d0cc1245f3f8b59b1684aa0c3ff1c928b8e880a3375ed811dffc991fd1d\nA = -50ff3e00feeb2efc6df6387d6409a622b7a8297a717b8d94d0dc41c6ec6f29a8455c3580019349660b31dea1e4f66b74147de93535e671c853b604ba06a9b62d34646c\nB = 49ff858c7081392defc3ba12ea8869fd61188ff15d9339be72657b00530b851de53b1fcbe16034816e73251fe1ec97bcecd8bccc470373974287ca328af\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2c88dc40414969e8b614bf8db05fbc38fb2b7ce144d7e707f9f8eca40ae2309c1fc67e713a8da5fbb20e808ad20aeb369cb72a77fd285e38a7895ec0fc795ade4ef1f1680f3a3b3cee4569cc9d5e699984daab3385815d2e515ba5d67d21dd1defc12ca81bc8ea645f8f8d103b4a0a9cdc92eb50690c07a037df274bbd5217e4\nA = -167ee0fa8e5d8b569d7848b068df06f6baed80f6fa6a442f9d11d9712622b512249b92c7ccb821ac751fe4ec0a7a47e04ea5571c7cb45a7985749ecdd87f0c0faea01d232\nB = -2207fd8dbf2b8e9a5e3cc515479cde241dd3671803f9fbf7859459ac66705be055fa759c85631ed2a61139657eee7eb08fd963b49e33666e60b7e75dd26b5d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 674885ca3ef617a53eaedb9564cf96bcde131760ac541a81f4b25c174a6fe1444c2c206f7171e343e1bb43f81610162994c497419e75aaa25b664c122ed2b27640b45bf646fc5da1703fbf1cc66e10a3c306eb69ae5f937081a1a18dfc8db376ea18f4c1c499109b0cf8806eb32cb1f28985da790047bd7b32c1f67bffb9761\nA = 413cbcbbb5851a4ae12555801f7f80ccd888bb82ef1b5c31b99e1901d7e0ab91ee489c84044bc21fa2010f11aac21d0531fac09feb482fda579cb9f224c3149dd6249b0225a\nB = 1b6bfea70f1d80350eeb45f9a5cebda954d72cf5cd27a299ef5a42e1ed0b50a541d1657b70e50b0cab69b22e31d0944fd735957b1ff764865d9385af302bb802b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8d74ba5fdc67733ced4d468f6eb6ec4c1ebd79c97682c1d4daa06105788ed9c5144992e555d903804d7ed0dd9b29ef2648568ab7ff462a03e0bceb5482485afc3b91448fcfeba435dc587db6f3a022428d37fa0e85392d0e48e7d4ed6b21253084e653da8175587b3b709e28426cddfec8d9dc582d4ac2f3d540305c0fe17327\nA = 17c0b7f0e2cdf316e4d32f040e26d41dbde1e6689d98f0652da1c380daf5dfeb6a511b72d82f1b32d3852e9aa2f594be10776a8fc89a8a35c160e8e41b42a06a342fa1c309fd82\nB = -d7b7701340c5a358455ca5fa314ad83860d9f765978ff652d7f542de2e123bb976930b8fe84b9608648324450d8ed2bac4e44f2fc71711ae813cd8793af8d3796e8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 57e60f79b4e156ccec4c253e70df8d86e4aef326150d612a5ac4dc285761e88ede412d28d9dfa5a6f5c073d3c91a65ba9c86067d81f296935f0d0ebd2af82e7f6b5b336422429cc3b8427fd8d3f5a6fe936f4208362632093bdd3cec1aa8f4b176d260f605caf4a12cc011f3d1b76135ac2507346674e41673eb16c0f55d8010\nA = -4f1568c207a9ec970b5c26f068f3cc8019e8cb483525d251cd2919b368d072ac8f40017a19fc7437cf88e927c9e7d6f539ee84865f0af24be0d6d98fb33d74e3e0d28020c00bcd61\nB = 723db98a78f42aa45496f31cf78695583526d25e167da48ec310e447ad3540be2636813a2c2f7b8c622795ac451992e91bb8e43e5737f0dd95623282e729d815b08ed8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 237eb5726e2c628a515104bafd44348dbf099569815784eca5d6a415d3c12421c8c70fee23d6d82f7b5b136b70ffed3b6d9e98cb47854e79239d96c26f2ec955e4ea8dabc29a1b0765c9b7af6ef09ca673d1ee21c680e4b8cfebf47bbc74c993d017ead6cb6f3319ce4de9e9765cdb3ed8fcc57a1b153327e1a6a965e5dfa89\nA = -1fd1f634685eb1470dd9080529a891253a28a0b31e15c662733e20d43fc4cd71f4cfe83c3774adf8293a0fc3bd806d0b31b61c6ed0b4414ccdb91e2994e22797e5771c63defcc0887f1\nB = -3ec0478afdf54c949a097ca411be41f931acb750ef4f0ce97d0f0fc77cf15970cfbe24b170aa332de04836b7a0e6c5d456814182d27c8310d5fb662a818bc421587d95fc5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f1d500443fc4f4b86e7ec93e4d0dfd3faabda35a6dd31445021928373be14c37fec369ce80ebcb77aff2151b7ea94d21592da1823ebfa0af196f286d7a69ea54799573bdcd4d09ca4f33b8a3a93b35de5ff7f65099d59367914f1c79440b471ced6773b0802bd8ca99cf531b62892eb1e78d67f8210592208859b0aa1754b14\nA = 572de2984fe2ed0d5ebb5bc3f62b197fd592795d91cb16b48a0c898991ee3e884e5870b92405f248036ef9b3898c5ee6100a09ede5a48bf7edf3a067e4fc77e7e6bf6a6e3d4f538e3d66f\nB = 12c379402b18a34dc8b80c0dcd25be16c99d6f76d5d64b6050b90910cce594bc022794640735710c7ded857ebd44fe5b2e51574a2296f7d7a61b59c0123051bf2ba4a168cf8f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4001c734e1391a88640007893f167eb79ef61e4717d5eb14b8d80c25ed59c753be63fc8e54bdaded22c9c7d3e49753eb49efa010439807dba0d90ec4f9b498aa97f109af542bb41922936223213ddedac4d0fad8f1446498f4228b758aafdf1d9692f59029c76ca2832125ba50e811cb95f2b982a7a4d87b4726e6dd8b1963fe\nA = 16792909716b581a936287d0a8550a1f3e840935f0f3ddca75aa32e3489269b078fd19a16f8d6b2326eebaf46da76e90890c0ead3b35689bfda8c1ead17a4f672588f982cfd3da2c2b9bdad9\nB = -95ab2c47f85001aa852d6999f29644a6a55f9e4e12bf905f911f90d29cd1e4fa4fc9d1a2aa6c215bcb5c5643561499aab8f2678fdc5fa9c6ec138aeb2d62f635c45f239e46b0fa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d1", - "5896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1bfad44b58d3f8bc987116d4cc7ac98f89f838a8712d81d726189e9e1469cf46fe04675dc0b82e6e556b02c350ef4e30ec6203c7f1df937ea80f435af7c10f48538fe7755ba78993f304e64ca0d783b0f46f61bd14fd3fd30768f233c59018ce911a94b495f58eb96438e416ca3c7eba5b1bca9dea5a770c1d2d9f2f62f821e5\nA = -78a6a6ef40e443c52036e75f0b35938d632bd45aebf45a1fff5c2e1b6f601a57382b9a82c3e8b2984e643eb1570cd83f3a6be6daac567ddf9f37bd96785662bc3cfee6f47503d239c77781a8df\nB = 4920f870cf9f371050e64a419ebe07ac92dd3525b41e8ecf6939a267e1ba853d54862dfc95dd21b3526eb0a0a7a7f8fb67df2e9472dbec81e15cb13266257177c5f2b92fced4cea5d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6b0b84505907a5ca37abeff9a5ba169975792c69b5751d9845c0f09dea833fb679c8dfbf3895bc470529e0cc736c9b4a0d08b75d709a1d04525ae583c5ba082d3bca1355055c7bb674aa1b92689cfdec4dbac84a96e81c855280e417f60e7e4931ef4f428420c0b85d2cd11c1030a47788d6ee6af0a76b5364fcf23b270e9d4f\nA = -143d843e3b12431fa0d873815a757a214cf731c298db61ab13cb87fe78b0a6184bd1fdcfec0c7661b10775b4ee2c815dede0ed497977c9ec5154f7b24a8a786501ddb8dd257bea51b9fd9401ff760\nB = -25d4da7b64f439987eacbde66abadf0da7c1653c1c1c6d9b2092351fbc714a20d2d7ad8093209da371150b69b3602480595533ecc1f3c5005a8ead10732272246d8cdfbab87c49e65223\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6bce40524278ce242b0b5292d27751a3dc414f962d9c1cacb45fa3ee693ac6890d2ff1647abe578c40ea8d4b326a2e0e2fa7cdec28fe2da089338b5fed91c4277cc5be37537eec2f17edbf48a45fbe38f15c58c3e733d408d001262dbd40c9d246c323e7978df4fb7207aa9270a12921743cee2a483e7e71b221b09a6b2c667a\nA = 402671b0cfe14655bc650bd35dd0c36ce7f65de274a0cc4b708c6f6c3e84c2125ab2430e702421904950b29aa8a03b049910305127890457cd0cc97a3e05df67f29d28b0452969986959df02f59d207\nB = 1648c29205f19fe4c646eb62e8ae9b65260c2cb8424a526423c6bc04ed55870cefef9b8ba808f8ed2e1ab170e2e411f68b934abb1a22776969f79f9420f8bcbef28417582942e26646af60a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 40db38dcdc201648da555f1062bbbb92c632c29b66902eabf90d98dec69ab3f3b28e60cad1571e7246f4c9e6aa62ad26a6d0bc08598c7a8571fa830cae4c2875c5c95a59f3295f998681edba7749b7e38cbece8887a7823b4752165e1a897e638836d408f439f009d0fb6c196e83e83ca3289d2bd0f0eb36b721331e4f9f80fd\nA = 14361ace8ec5223bf0165b78913b77ef921b7089bb5e28891d120bd3db6513ddc90404a4e6cd027f9b51fbc02e80d376d59e1f2b043954199ef8218bf26cacdc5e749f668ad3b4ab35cd796f94c06307e6\nB = -851a39d8b0101fdb22ea9e367286e572dd132b8a77a6a14dd0e995131467aee898230f37dc6224e35bed2eaf459aae579181a161450bd7ebe6b62ea7154a8a0ab590ca4a6c2f05531c4e24650\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4b085796665458b798f824d1c1a88c23ecca456fb88713b433228ca8735141a616633ccec4bc53ea4f6e0c74e4aab6fece2e4cc4c4efb479638cf54caf55d4addf75908076f5fb487ed00d540e5b984acb8f81cae3ef51db926a06382a288092b352793de721c23c371fd0ce7a789486b2e8b867d35f47b5daac2d339d22dbde\nA = -511565611538828ff7dbc45c273fe46f4f5105d41ccf5dd343b41e9dc579429e56a9cefc54657ef0422960d1375b72411a5cc93ffa323455e006e242580358d6cfb641f46b9c36fa777a613b17dd4a187454\nB = 4f22597947638b9a9e9b9b7c2a8d37f77259f1bb1c7db65003b6e1a1c807469c84c89a75b80bbe0324fc3aeefaedc6ad9c0d9e470dac9c30bc48f6abbbdce9547ad7624f0ce9ff3cb6be23e47bc7\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b90a57349ea94ea818207fe15c164f9d3530c7cdffcae178557274552f79c4ab56acd78033a570bd6c3e45789704ef0b0ef586594fe4cae3ccfbf9ceef46e769589b084adcee3ef8345375b7103232465b991273df724964248737d5eccbac558e35e4190112571d3e7c291baa7aa8b1800121bd573b8419f627c0091e1bba8\nA = -170cc62ad57094d307ce1b317ae5e825c2f2e317ad6060437afa105501caea00dc9a86af8729e2f3c3a854387dc3ba368c0a84aab1a527ab34fe27b0a69bc71c728cca87be728457c65eea7d7538ef3aa282615\nB = -3d9da1377a88f647de57ade46dc7caf71b4f42bbfaa5e77f16cfcc90f00b5d3e9e9d82355104c7cd0db4c1dac0496be3aa35706cfc0a30a1329755faa439694e8e9b41fba8f1ebb46140818c7008e27\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4cd4da762c7576d582572d3427abc4b4297f740705fc14a32b46347541b152d0d1e3a11f27213badcea1e2009e34a63350c7a59e4d43654b28298d2757d6b54c4d82f580e98de4230cd119ba350416452cd4b8adff29b9f35ae0c533f666cfed716838e2b91941dfbea8d6a978a369d5f27554ef411f15e5a89850655d7f3f5a\nA = 4f4a28af27b926d8ac347503d6ac0bfec388a6c0b38a577501c3ca4aa709c69601824ddeb5eba4d9e437a97f3e4477e1487d5ce7b4a35b90fb863657a5b2d901bb8c3c838db40b89b495ee9875e8eee607d7b8013\nB = 13ca192603bc8b2da29dae67159e4f8d32f351a503434ed9e4e24f74abb5908ef7da80781c71b1a5ce64fefd13a16cc1eab05a370bfba2a97e6cf90cfe98d3a487ba72dde0762c36c10e1da175f1c1b5fc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3812e9e835ae355fdf328b29ed8b86dc3f6895e379b8b5d65a5de41eab5fb20ad3e2290c8ca69f9500248ff883d9715f59d0db6257d13c5cd612211bb1fb99867161daffc77968bdffc1fe48bcde0fcce02ca93975b3cd9e93b56974ab4beb59582c3d0ef2a65957f701549f8bf858de0c5bc98af3e5722f1450de391876a2d9\nA = 14ca6101af00d67139b985ac9f149accc260336237dd2dee802b5cc6e506e217b74c1a007ec10c20012f071ddad34e7407012669109ec1f385566ff04cf1a1ab7562353c0af1ba1be0baaef920a188c60db27970f64d\nB = -94b683326e9de19e414f653aeb2cb4bd7b17e76a23de6a4d91c43d717a35e08f2155b444a9549dfd01a8aec4dc901ea9f629f16bafd2c84828b12d2f63dc154323eb2d54938895ec4c9efbcaaede274fd4ab\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5ad7411cef0581b2e675d03b0ecb9969102a283eba5e779bdcbb7646d94e843083a07269c932d18b973b57abe54eaaad0aa76cf7b61f30505a263bc95aa063efb264ae829eb1d1d5f7d380a0b4db59839de9ae6230ba51901e71b3e3d59e8c34a79678e751c8b7ab139123bdb2f04d90a18ed81d2046ae86da1a73c8dae4fc4f\nA = -469f61cbff01f0e4124ba69a860ec6dbc75cd758dd8ac7cbfed97645b16488a329adee62d1a66e90ee4212569d56d58b61676262f49dcb68296bbe5d8e23853e3fefe8a304710cea568ca65c183531a992ec5b4d82e226\nB = 4a0d48e31cb8c24a3b2c9c95fd19edbe46823032ef4c97fe65d0a30d5c2cad7a4fbbe89e0ebc9940ed9f9ccb8ab18bac269759a9740a7985809d0f38259e680f0703febe7fa012d1ded47f0cace4a133f59a721\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b2953981db406ebc544c39dfeb08a8b089064533221536c7fa2bf2a7a0d3a1192859b7dc0ea5036eeab5aa371e3e0070c3980433adb3e3a5202ff257bb546bcb9550423201a35501fd717ed4c0016eb3a675ed399340bac7f058a04e69c1774590fe747ffb9c27e78ba50fcee30ce533a1659fc49dc080a60f21357a6265d24\nA = -122621d97f42b65b060c84df3f0c0da097b5e240731b77a37bb9471e7e398b242db6f1b5e25062a9bed702860ccf6aaf386c1d6fcf60fc31b8c190d348", - "6949c5772b9e621b863a7cbf29449ddd68b7e0c21e669492e58e94a\nB = -33978406dd30ec2b192c416e422428683deac210017cac9e4355e8446d6969295b0fbaa8cabc92c1fc0068da70efa047f938a419bac160ed6f794a9f69f53a88648c9725610d5f309b652f5462bd3011cf68ea859b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2104dfef151526e072c09a4a277eb981a035379de3b1a55a88cb060681706f26131c388f5572c5646826b119c85ed450207f32733487e3c4e1e9d701a65058c4b4ef0cd1db090495643038229ed177b54695ac32110619038f1c1cece14faa693d88476e3d70329b0084d0ba5d547bbaa5b59ba1ce1fad5aa2f1c11a75bc7c0\nA = 7b79e6f1330fefffaf8521089c3348593e40ab7e8d4da3d4346571b43b12740958336580afd13619be3dc2d42eefd9e30599405da3e32e7f3a5655ece8b77a367059668021aa092460de75e627526da08e6206b0f8f539ef40e\nB = 156e234931907c0c0970c1fe6bd4b24225ed94d5f5b1be4693c8e141e9a6032425b4a47b6eac6265afbeb9d796eb230efa707d5ac4a73808225181cf814b319142e9d175ac461c75e6d479bb6bea53954bb981062eb16\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2a392c5fc96c29df2f5ae9eaf76e7d981dc1e2f3b47b43a98eaf556a9465ae8727c622188123c64658053ec50c25e54ac5c6c8bc279b134d326e911f14c873357647866eccb4f9038ed0cef5082c2058ebd71e1619f7c8f8f2fb80871ebbca3fbfb7845bd855d307d2efd853f1bfd467fbe030862f165e53a9cfa633d0d3fa23\nA = 1e0430e7cf15173d00592037e83e717c90d7dab4f54a5b2f0f5772762fb5f56bc0b2a53ec1bc3b960afc35e7b043f9d85d0af6c29288486af3e186e52bae6300b58917647231b40a12648cc8c020a797683a9bd7ff34eb6d41b928\nB = -e08372fc766eba6e0ef55a9149d700b503e2e3f978c8a397912e2735d5bcff69c461561ac0822c44160c7c1bbf722df421b74beada57462ac54a9bdcdb42d6a27b86413036ed2282abf62800fb2518a32a4a135bc948053\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2608f68632ef14dc3979725c8cf1a0db10a1651f17d91247edfae9935b53f6364d233b030eb99871a87b7bd876ab2cfd5a643387a7af9d337e81770db04a14f4f8dbda2cff604838c9af9a31e8dccf9277d453176589ba33abf77855b9501e63370b2e6cd22831e1e70ff1815302c0a026c70042957d08e74dfaff940a91a7b9\nA = -5d3568858c05a15bc9777af949eb01d33dfdba58439fb3f7af2ba792efe8e78b16d7fbc2a303a4c4c4be7c9d43f57405e88be54d6ab55268a4739945ef582921d2877019659dadbc76e0939f4b2cfbc91e5356ba2ed531526ed5b9b3\nB = 47f81f65ea1af04f702757c02a175a299b23cd8ad551fdb67020c50cbb4110b5371dc5790b12484e9ce647eeb24c0220a5e62aaec3461a9dcdaf1a22814b6f22d66372cc5ee31944bef33469f905458c172ec7871d9dc9c301\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5735109bd21d31b5f54e9221bbed78c54cf387e39c13d31557e8173e173f786b2d2f1acf3966c3bf4552fe9bc802d0868a5a7632404cb91609a7a45fe0fb83fea8d83b0319666c1b0ac520169c15be708343359447f2fd37960c1e96d32799ac9394e839b391f59dd347acfb79bcc4e34e76490880d163ac97ee69e3a0a6e68f\nA = -175011349a0a1ceba11756bd528f2bd631c106e709aab223032d08d52d7d6724e8c5b055b6f97b48261f4860eae297badc1214cdae9b2500a7a47b4b777dd7b8f1006757754ff1143b637d2a3adc555f38eafbd5478cde0b04e5f46d3f0\nB = -2aa7f75d6801b04ea9f690aa0c5448906595fd28b53775059c01efe54b463f1d87c9fb4b39cb038e770f99bb995a2118b86ff8d004bd964e958c2af82becf362fb0b927c671cc3bd7185990419d26a827a2d81bbc0126e1029556\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3b4ad19b75e1301d19b57ba9b68e0666c28c7c5c99df1d5fbbe0685dc1d3489ff39c919222719c5d8b7ce2d7ff967730d776a02b36a86064ed66a02011bab82eb575390f85f0104715f6e4954a1bb28518450182a8ef58af35d00e2fe417f07ba25dd9c85e00c3451082becd22e3aa0c9bcedaa96e6423c7df6c375b4c799c65\nA = 58e1ce4a9b512eb0632b02cf1207936d6707b802140540fbcbbdd712e5ac1426b4f36e74a9a9ddc812e572855d4fe4fca8a0de6644226f5698fb46a5f2a479dfc8b588aa8e02ddb15acdc79ed3d17143e290f1317274f425b869df54a4807\nB = 14e341cbb5f5a7f3b4dd864172b82ceed2887fcf20aae7d0598b3d8afafd2f10c27bc7456c1488abb570be3df04f43d892dc6a8dbe7621f55bccb0ee3acb1ade989a510b4e0cbe29b6b93968f323f0016d87944c908824d249769f8b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7fe0bbbccad6032069b1a335b3f2dac16089051cd9321f903181fad23be6853e2d209958e8c48e008be94a62c6206b34b4e994ca08b8f24a2df0e6394ea65b3b7aadb3bc43d04dc9d35a77e673c4476dedefd4568b4ade5d16f9d89486f3d5ed0566b1eb428cb0b688f10fe3901037744f278385754fca481f937cb630f60308\nA = 1cc0e3ed58090db55063c9ba11401636f89262d6ec096d361f448496e05181c5f7f2604333f26d511c13534618e90637adc807d622097f7eabfc03266135cb626e1bad20997e72da71bf2b3f65a4973dc27d2a594b1fd96b7bf7ec14b9e4b983\nB = -87871b2058d33cb67d83b6a56ab27839c6a6c771bd94e55f200a1257f2c737e39c4a0403fa410ea64e8f442d300df1c19c2f03d07fb74d94f86d26814fca23d4cd2cd3718252cf0cd8a0e36726f6e68827a1dab6bbb1d23b884381c702\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 35d7ac5cbc7e6c262ffa41be168b02a3bde9e112c512d1f68421d705ea34461ce3e0dafde67f44d44cf31d91b38d4d5f2fbf8c6c6a44ec3ed0298dd58f3d45c04346c11e57229dc3d2cdfea02c802732d9a811d7be5e81094d72172cd04caaa3c9d55a951c09f454f42add6e89e2d8a98e124aac86379df377606e7af9bc6baa\nA = -4ee01518f6581c560a186fa05c6f4bc26809c4822cc74a0bb74d5a6b0a368aa9bd0108f26113443422b8c589084ad49f919a9e7821d99127bb210670e732b7cdf610e464e300a39d3dfa7c82f90cf00ce329bc6763d7b1d4224a020095112fefa7\nB = 72dc8973f7af7122a05c90df190bbf1e39abca908c197590dc7ac41fd0712f48f838ca62a72a177a293ee6b2afa7a10c21e7993347c3df4f161a5641ff62ba123999bf1eabef29ec0d33ed0919818f4b7c35b5f41e654759fc9abdc0f80e7\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5d83a9b34631dd6c63c05a0c012adf97b4d0f20f61907e1c2145330211e9a7e38128517b058e0a85e993c385068d1cec768deb814bea1323dbd333de091ad2cad72431f20c1e70ff7e1b119768ba44e14292c38b88dae7e55ac9e10ff98e9bcd5f0ac05af499196b4be0c6222d1a63227ee895fa6a8221a4a182a1323183cd7f\nA = -17b3e0c9288be15fda58c8fd228216bc466731d631218a7ddf1d2c9cc858c0219cb0757d3b680bca1b1964eb15031b5b9d761a8bcbd160db89be339067a2ea35e1ac3cfed701912a17ef9ea03999d92e3592e893183ddc05cbb98a656983b54590c72\nB = -269f96a4634eb37cf8a6608408128587ba45958405a29827d0d03d34816fcb1a2297f1319485439d3e8594532545086efbe4d21d31d30e2daf09b74fa8cb27df54e8f9f993630cd9a292c977eee70887158bd3fa3cfef321ef900a0598ac8cea\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7fc1c65eade94d9de7440eb8dfaecf1004905135efd4f98257c3295b1e76ccf1e2ab6808d158d360b7419c6210c50efe960610973d9ae855c72ec0e81d423e5863c80b542ad455700d2d0dee5fc403dc01eab460c24687401cf6a3179642e59f2a30268df95fa80dcdac230702352bbf6b60acb9ff5d45c5b09a3403b954d173\nA = 7906bd8d3bebb1303c1df1fea0b2503b0abe9c69b4f4f5bd01eec9e314788cb7d44b93428adbcef570477e8ecac2a64822e481bdf520fc381e1bb0b2cdae2fe94e484cef5236dd524e4dc364b72", - "f4c06d57f29dd3c5079e532b1ab1e71dd6a65b3362df\nB = 1479ef2807b9c23c094d0416f513894cc92e023b134f44a5333360dbbe98b8161ab899302f4fa11b470b97dca0c4e8ab7ae47e5fd0962834e6cc1763618193f4ee027f667368da580c623080de137b5869c3081128e6081b9d5e2dbafd791773242\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 730c04094b1ce944588e8291f7e6cf763c70b79cf362dc8a1bc63bb8790cd4cfe4eb51cf15a45a8464d69ddc3e1b9383cfbfd643f317108cd9ca6a6eaaea177c5c8b6747bbf40108cbc0437eb8f11bd2a0939da59b70c0c6129e2c249823897f2ee536b0427bc45035f121d2cbe7441c175899b97c490e6c3ca01539bcd05848\nA = 102cf23cc3b81785c73ac3613c816de47fd585c7d5f175185818dbb4bf0bd47d0dda9702bce97b29d66e48bfaae0fd07b47b40be2b48ed702ef21c54b10bb927f9d6b43604bec4f4b2796b44aa6b4e83f8bcd00f2fa3871dd901570e1a32888d8691454c40\nB = -cc5349a9c5280a933e87ca38ce458a711c71ffebb40bb1f7612b42b4684afc495e99c4a5f32eef1c9564c2b7612ea4cda7a0f5df6b3ec9026447dc565ca08563d46aec7ced9fc4cc5645960210d44cdc3944149051d569c9295dc50862f8f6d1f6cd1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1cfe1842a53d00e4619265e2fce7cb566ffbd912c9213925d01408a956af304eacb85e29fb6edb812a95e90769bf1c3d62b0cf6cd5bb8f8992391d2ad70f38a14fb9d1d1eb522aa7b7fd9f1b52790beebfc887193882377b7ce567d317d8432e1d9a908d6ccfe8d2de7de497d77b023b3959cc042ae30aefcc0229617fd2a146\nA = -5c3d24fdb193ed83f5f6a825c1716f98e3cde6b32e09659f253ca3fd2a39402b5bc3a6497ed7bc908838e93422559a13cf59156254bd3fe1e3b8600b2a777943cdb39b9d42c58043f1d587424425d3ef5f5538ea157112970ce3e09a87fbb5f7c96f1b5e65fa\nB = 675d9d2a05288b438ddcb330acbd59e4639375f3f14ac2d0e9e8b72de6ffc1d217ce62f997577f7eaddbe4603541b132cd41f2f2740363d9c331ef22df92029d143fc8495ed0152b918aed7ff22f564c7cd94fd3fe4178c90365ace43def8fe30ab05c0e\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 83ed1948276d689bb7fde814e67fcea72c4e3509c48873c3e7349a8fa1c08ae11ea4d814d8deb1021eb8b8ceec342cba5002a2ca45d5f340ae1aa500af4c7db120d0402c6cc8a840404be7221bbc46ffa10236043e5ce4415d3ef1355bde26d2d26eb7127326d4b8d671bb96a08e38a2c1dcc281830ac77202903a5e4777ff02\nA = -1be86e7c87827922d2e8a06e3cd6b64ac9a280c525749bcdbfac4856916321a964c9346d17465378251e6eada42dadf38bc9d7d87367bec94ebdc21af6b1302e520db08a64ba6b39920683725ef02b011a3e4ba46ef0eefadb98582cb911d0cbeae9c231b5e432c\nB = -352059faf97b433089a688c702b97adefd0c91d51a0395647f822c6762fee3287693e302fc5a5584a12c048dea1a320cb96fa70b5daff7c2ea21d249467d14c6bbee15a1e94c030e908342a939fbe8ae0de58cb6d6eae7758485e392ff6d5d64465b701692c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 402525e19b6b68942253d1a51fd9b2ca36fc84cf938d80b3d52fd4302de142b9d93d1663e89340fff10c2b5efc8cd47fc3b5cc5ccd49a6ea3038ead6454bf190b7f88f52c56bcf00c6ad5b0f5dfb7615915ee8af137dd99cd3d21172ab772f36d291a6856a8e7912750139c09aa024b930a0a6b9eccc83c2c5c0ee2473ea32c\nA = 65e5db532ecae639bd56dd63045bca39b33b4d70b2db82ca3d0ee8ca436e671828cde80217b48eae7487fe110830589ab1be889f1e1463f3b0757d529b2f0cdd2ac92c35e8ec141885bbefb6040a3b5e00e64a541913a38fe05824a929f8c5a2c46568c61989c3ca7\nB = 1d9c73eef8373cbb1e8393feb26d55c33a245c33d7031c234abffb2f06a1601f7f3a79ef1e8664c51ce5dba5f5aaf3b9a9e42470d381219b4616ae93c7f6e64792d23bae523b6a224c1f714ebc82a11f9be42618922b8d2eb7b55e4d45572e68a19fb0ba72228b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7a9cdb5dcdfb6e04351057d731fddb9e85f41eb432f01c0d980673d294d05ba9b0180133a89930e74cfce78ed54991b494a19e7f80f310b85904784cebc5639bbc631e80751807868e7fe16719e8ffcd1f2cbd1b9f303c3ed488b647670be3080668b5fa0e53b6342c33c87f0ca1efe1ddb1c877bfe2556aeb61805b06f41343\nA = 1e412c3d66aea2c503f3aa5dbad368a61d969a2951c0094f9da32d2794e47f3bf4c481ae23636baabdebdcf0753d431426b1865e62de8eae7238a9245d62820ad7f17b5380d701f5db776cd4e1ddbdfd542901731ffcea5bcdc247fa9c83f7e08a9389e5a76d38be21bd\nB = -afd61df72361260484fade8b432713eb740df83a401d73492883a5139c918d5c911ff5dc00140637da1c6acfbab4b0bc8fc1f337243d90beeb1c2a083ad8069494c73a99372bd38712a5b5393c779ec1915e878600e0b48157bea44ca8e97c6099c4ab07fbda57d1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 712580a1ffde78c8cf98ba71843c8130e835fee3afbb45e372d04c04cc388e403c9efac742611d7974bbae982c3aadfd1893f5da280afe0c1db1d81a9ed73b6ed9b7f05a20ce828316103259112d7754560d66733041e9470ae0d4dc95fd0484bfd56d66739f38ead7efa4051187ea41f7bea8fe5d958a29af41328246e2bc35\nA = -47c5755ca61ca8b7ea927f6fbe347f1362915548ab38c40f0418f4c9ba4ad520c3b2469d9ba3976669dec0b278461bae80eda53e9d11447512963e797f45460f74678acdd69fb9efe3897913b6568f8e03a6d90b4cb5bfb06af132bf118574b70e6bd2f6d6cb4d0089379d\nB = 5bda68c0a64218d3609d75eb4832d5468298f19498507d7d515f4c410f04dee535947571a5e75f1af7f94a5b3b05fb742fde23e7cf3f8b3dbee0a569e5a36d7a3d31a26c4a48a299044fd72339d2cee1a68966c851e76b93ae34130b75f4abe4f2260207d2254d23f56\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4a1a514aa4d1ada84fa841d0b668930c904783fac521377a7d622201867d773ad23dbb667e0d4181616358f3cb088cd157c8e72bcd03db64647b37aa1813f870cbb0318ae0a3667f8e6c19f6e0706217646ce633f0cc8bf4e8f0f4d7329a8647252ca6d376416d545e73cb9a3cba40f8f9465d85d57c2481b84b6d95dd42d50a\nA = -1d68bddd8c3e6b78daa0acfc63a6f39e97f19527a43f6cdec47568d57b47f4e4b7ee88e4a28d683b569e406ecd2510351dba25f10b9f7c82d6da16d848bb970cedf7675e67937921bd334eec4bc8fde83d67aca57eec804ce22bb342167602fbff452d5f0f2a7f38b576e1e50\nB = -34d219765916a4c8ec843ebee9a7aa1162974d41cb4d6b60532513608452da9993749455d9701af6b7b6c7454d7f2fd5c344cc938baa5259301d4b56ae8d25b6f6510ae6bca114cae6791fa5a9551e8a405f5b1c0bbfc27138563b2d64f9a4d7a8f42a23bfacc3f1ec9393\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3fe24e66e381eca525b24cf767215837019f44ed4fac6ab118d02cdbd658066505ee5b0feb7af51859992ecb97d727121e38873f748a61d70201cc43228a7732156a80dbe399e05764be19e37dc1b93222bcdcbc45b1a4817460f7021dcf1d70e632bc6a306628790201222bb522f4cc80adcc907463a539b02f74004d42adff\nA = 773454a43f495959dd55b8a064d70b1b1ffe45c084f5f9553582e24fb402b564de68e5379a8d9d02af101594e717a6c6db2e7173e557a64d2f28fd45c4e06041deda040705d99acacf8086830af19c7ab5e27f91738ffbd937dc27e5b7869bb6caa12c2d7930366ff75eadc570a\nB = 13d884a2396268f1a8186748a15722156a172a56dd3d8c77b9cb7001b6ee06720653507eba9bb9918f2f699cb37f3b5ae514f5180108a704647f19b0fc075826153edda66dc1105c1008ea8ec6f8c10057f8e8e479e1a1274edfed9ef719b30827a30f26da78820c3696d01aa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 715bab8708e53f76d2ef2afbb", - "845bdaaf978b54ce25f84dbbf9074f16d30a18733a02a4ba5d7b092fa6c25d3b9b0d8243c743910f1b7b785d9cb02343fc6d59eb0817bcff05646030ce4fbb2b9ff76781cb1af66b46553d365d02c61e677ae97defe92d057d4378dadf8cba9824b0022c086e0d78b5442bf3d3263ba22c643f7\nA = 168186208c734383d472374fbedc2d5d430e85690a4881b740008623120a4f7f83b2cdf85dc28bfaae5870abcd7ff1bc782ef11c78a75c99d41f8aacb52fceeb5f10266dc65eb00b0868937340146d8850887686d54218badb97647a6d82c0c6650ca1f9078d73fc6222aab95c2967\nB = -9711e5b3965654bd9427f79c89a0b3f3cdec1c857f4451eec236c1f221bb6773e5dcc30e7381a18a813ac2b03ff4a4ba679aad41e0e5d7181d4627f682ca2dc8af9a8b4f878771446fb225a979ef9c7e641cac819c307c8dc50d9c1ebadf912ec7c844e416f95b546cf09391f9f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2714b99dcde70d6c3be8b671d78abc155793f13105fd4b7c5d760a4c68ae89987311dabf2a9238d18299f983b8aca69a9ce398fdf2c9775d90b11b3dba17bcd8edf661efb6e9c50b4e37553cbecb54eb214fed1d0847287732810e550a4c86b51d4e5da1cb7722ce4317e69644620ad806d6d1c94e1e3fb4d87de6178a997453\nA = -75231ed37f1dfa4487c9fc79a6f7b36929fdca086e42ed41f79430b2dff521919236fe415ccce590e1d3b986e16dda866f3f0d29ac1adcf55d87fa5cb67dbf4693293188516e360bac513303769c42181483fbef7abcbc4fea1310c916396d29f37d9058a62aead94511aded7c4b8de8\nB = 5aadfe65df0e5b877fe45d42d7ca02882cb6c686d486374da5ece6f87771675153c84d74b6f40df1db567b7e1e3c60c41d21816f958f5576fd2ce2f84a8c3be4749dfc7e5561266b7c9698c7581292d0d813cb77955458d63bf94ce87472924c4ca79504d1ae9d5f025c7a2504156f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6613b1c8ccac0cb8fe2f59e76fef4dd05acf1f1b2bfc20aa3f193622ce3e9d4c7824ad544477553bc68f05f0b546e7c1ee87301e111af7929d1f40525291b88e211db7175f4e5c0953141914fcb4fb951dbf77442e7cb28fde495704f1b5141de1e50fbd0e359d0d86ad709c8f564c84dac81c7602717c269219ab1cf12e809c\nA = -1bc03897b02d1edb633e2c019e40c20c1d89a210b0733412aab675563fae8bd75dd7e65988cd8df4d9b343586e27f548becdde274f62dd421679554ed9eb127e527a69d69fa8b17aac0424dfa2a7692d1e63617ea45564b55f01a70325bca050862d583cdad96c4a2e123d0ed827348a745\nB = -3d5239dbe7bb3dcfd8027204eccf5e9444e68d322a0b0c535a203a1d0c054e7dc1e588bacb891388241462a5d2b43e6cce34ce46a23e6ef29670603d31001374dfa347dfcc794988e58945d0d2d17da6565cfea559203dec119fc357d396f65b296deb07686b0ad2d25a13fd4fad88d2c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3a7fc5680aae875b9241200b9f4112a82cd624ffd9044138ae3cd65200631ee9d7b918fbffadcad7e598791a9f0bef3e23005d6bc0048ba92461283492df3bce74c66e417b082ee052fd8f808d71f3ab18f9ffc40f8fb51ebbb936d09c26a3514bf868141f7cf238c1abb3d88e5d50dfc188902254f07d63fb8cb611ef8e4149\nA = 4a30f32d467b29dc83b40bca2fc4ccee5f08a64069cb87f20e63387b2219b12aa312400c4ca59608f50a71d2535cde40a6d248290793fe01693ca40b93a5cded2dcfbc9aeb36e187c9d650782d12bea917daadbc6525f266e074037803e4b2f300778ca8dcb304658cdb502c93c94a16c6261\nB = 1ca5e5218dade077fecb81d579e1c9290431b34df5ec84aefaaf233d68f17dcf60ee010db26320685af13a821b6daa9d73d8f3a30826c3ae7b2bc5e219cadcff826283cd7dddd04cea7a5e0585d6e7c9f23b27f14ff815fe53bcd75fe700b1b91671bddaba737fb43bfecd2a77e5b752a206\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 768d312175ce7d2601f30bb38339f046e4c2ba5c19ae5f7ca5a562cc2462c579fce9985e9e8afe2578db542c8d9e7693e0c74ba161334b249ce720d568e9c18f09c87cd701e6f2080b752362f2fe6252a1d0caaaf1fa18199776e4c6078d89d520b9c63db159d5fba7e0838811e68794b1413c248f3f7173ef29eff28f15b656\nA = 149353e91bdb70cdca8f06648388508511a64d05221305cad7187ea40d9ccef91fe17ceb1e79667bf66e8e6b7a57faa90a83bad119c02984a8f860bc1f23ffd33d4ad84896610301cd2e8e80a5ca7e8d3ee63e7dfa459793c9dbaef3569eb4f8a021c6a3d032a9c94d3f6b8278274d0088a98228\nB = -a7cbbb6a434e4b022d312ecd4a45fc7fc4d3aaca038cca0fc56e529fe7119ccdddc8e76d51a2fb862ad3d27a16ec8a51e5f66b9c7fdfbddcd05a0ddea14172339cee340c8c651eb653c6aab6551c99ae94f26116e15dc62f2c2e63305bbf84590fba1327ee721150d46464d7e22d45d53ffd44\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 763912f4b16549e6ccd60eaf7a0a1f64d9c3bc83e4a9b87e209a3959ba3cf609cf47183bc543f08e346b6e12b8bdd5d1c07c603f74b286ad432d58d7001299ec7a4dcdb56ca875dfc7ee5c75bcfe2aaba14959bf3facaebf8df92bc12937cfd4a4865b3dd74b243ff62ba256d110b01b4089730cf48efdc66fe272f9241014e\nA = -4df3899b40d51c83dacb442fb143835bcdb550136921df78800f0515a6cee77fe3236dadd2a0800b79ebdaaf8cf4aba5ebb60cdff3e4b4531ecd0903c1674a4559339123e9f09158080fc53c4c6ae72c961c8da2f357b7c05368157b4956e592c41b25642457651abfecb4fed5d9fc1fc3825b772d\nB = 450eff382e73f2f38bc3a4abecd5f8de478f80a6b99fb6252173c90d7099629afe859442bb1f796855ee9a2940f21d1f9dc44f462edd74b479e1f2926ff6faefeb55adbc6152b5c97967b1dc8c44dfb85b5e02e870d2920b75422c8a427e99e35e2a4be92cb0ddc04cb7f4044f716be97b36f045a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 56ef57d56c6d1b94cf0fcdedd3611a8ee444c2e25522b9ad175587619598da341916b183be03b1e73be300f9969120d8f3a23750cd8c4ffdb87124a2139e8ff2c15d8dc944bc3c3a066aa16dbe6dba4a74925e16acdb2b2e83cd7fd5cedade6a7f7409a509c00dadc182b2860609cc9a375cb8bbdcc350bcb2c0df9b3bff882e\nA = -143caf995b7783b1316b5551978727f06512fe114b419c735b3381ec351275fb7fbd6ca88b848c3e8c9faedebd6d084cb8a231636f68f6803d14bafd90534609d4a4ac0fb953417be7fee4e4cfefa452c5ee5d1e1b97ee75f83cca8691a0efeaa8bcc1f1e0f18c0c5d6c7684c9da6c9495d31a32f40a5\nB = -3025fa05c55826c40089b12741b7d406f748cabf692bb0227519a124653160142633700e3c0676000943556f97551171d231c1a35f7b7d8f96b0366eb74942466ceb4660f09aecb2fb2ac050ef699eb05bd8834a2ba959ac71550b5c026b9093c8cbbb7c5fb9390a7818db682b7c11e58996c9d0add5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 42f363c34c20c443c1ea7a1c54f98c6977b6671164a80308000533b2404a7f280adb1f3b98101cba25249131288f7ac68b0ae2572c7777e7381c1f4d05fd82188c4b1ed5636652e0bfca4d096bbf4189a9358b79f6b6333b99e5c4b7a940c2f7d1413bf9f47a2ef66b620b5e220b2c3dd7267452eb1b9d8d9cfb17bbfcdb6abb\nA = 499d05de867bda3118a8cb82b80ac91fc505e0fbc6c7dac5fb61713cb6e715f56a31ae8af4b400461d7ad1687a2631faecd90d7829f67d1b9e36ed7d55704b3f2aea65eac061172d698384daea710ed92cf1140cd4da427174bebd173c2ff1675b2407a84649b0a318602f33105006fe4d5ed8d0e015b99\nB = 17a426a12a0175bb46bf7a7e727eb5238af383cee6f4d5e2bd82b0d29b9fed35f3d8ec95cfdfcac49bee47b25d3b5f375a3340fa83f8dd9330a593a974d208debb7e567e59dbb7251b54e42dab2cd50fc63aab050a41bd88282373f8195c94c35f61bb48aa921f574cb4ff0984ccedc070efea8c46e5cf8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f03374e9596cb56cbbd89794090ca7a4b437f4c05fa38a09db60e5ca900b208fb85b52f71c29fd35e62c9f9529d7ffe46fcc54607ccb07f6f8e13fdd4ff1185033ba4fcefb1ed4bfc42c3ea9f05276767d8dc9b7b4aea4c8bc0ce84951d1f590cec0751f73667db19060e2bff64da30fc048a", - "1f5700fe3f489920675cc3540a\nA = 1073531f678877ba854fd1e7f857659614c526847ffbe8ed131dc9f2ccf69e1f1e917bb44a7b905f7ff758f61c06dd59ee09567d9f0df2550fcb98b776ed1381ce052988aa08fc5153e31c621c6a51ca61b386e3a9163a5cd69608b3e200476a8ada35d906c41d044bafe71ef5c6f732935f15b53bf36f7ef8\nB = -de3563925474e5408e245184b57f328e265b6cb62eedcaba809d8f257eccc0a457eeb82c451f93af93ce9f36dd1aab386e7c02b356f31c2d170169dbe15e70cf5bb9073b35fe0e7c7fd7faa91c5b2b0740734f12eb741a9d9ac6dcf7cff59f6e16324ea39e1e07dc5b9daea27ac674dfe5d0a5790abaebde9\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1aa22f9013bc1cdebbdfecedf710c1bcaa41c696a3d7dfc1c8c601fcfcc1c85c8cc24be7df2cf3c7311b3b17a4ef2dbce545dc467d2a92d371e02a196a9977cb9042b236acf99d8c0d34a1c4dd8792d3497cffbc87c397ccee5d01fc2c89ef051324a7061e423720d0a3821a36739797393bdf7a45b5fc600824a17043312bc\nA = -4fb2e3fde2a0c653104c077cc6459c9234f86cc2d7b317329b68289826d3e2b975f1a69bed1a53418a0dd86e1b2723f4c4c5a29d003161e667c2315ec24a36f8bb5f2eb0a94f261e791bb829db685cd0ec9e1e301dc140ea57cac1da228124ae029e2b8ab1fa3ab99c55a9ca94dc7b767162c0a24af851fbb984\nB = 63702537a07971e399aa9a1a0795db052d6c8185c79107216babe11d6d8d472b61e604cecf9eaa6d44a2fcdd1ef0b6b52226ea0c6902d929b09e16576e6d1a6921765b2134c5d23c69ed61f36ea9a5552e5819350366240693558fac7a9d09ecd3702076c8c758a4bf6843fa843dfd688bef3f73515db31bfc26\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6acb23ea695d4b60cce53079390da3cb3a4bc3a6486c238c421f3bf6c93c027a0475f656c3e5435f0211e90458ae81772aa956ef284093020f7b58ccd9373f3fdd39fdf4adb8dd64590f4a7fc05238ba20017bdad07f5f9a6f076b71554a7741bdd8c98ec68f8fee88396cb1f47c64d6da4c228caa3dfc7a9a1c032a9ba4fedc\nA = -1b2496ef929bc673042996ae80f27c6bbd33fa7c20580240ef8fba985d1a6117d6e746989924e34f281e7d2509175d0773dd999bde16662e88fcef52978d19cc45fbae3997fa580a66171d398f4f0e7605d9f4aa4f728902cb886e6b6dc9f0161e7cf1ebac05a09c5a1bd69a92273280758173fd2c14550ec221275\nB = -28399206ae2820d26a5aa0bddc4903776611d08fc4cb34a22a8bdc2a19e9f8cdab94217f346a8070a4145f989e1dfb49cfd100267635af0e062872cc879c534ff138fca603b5d45a6860ea85b6de37cfca000c81fcda3d14ffe81da919b2a25214209b085bab9cb511889665fc845acbcd038711533da171d8308aa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = c012c4d17ea4c95a360218adfc3363f6d89f5aa524aec70049ef94c2c05e59a66ce01e25588e164bf2412f9517b7740de53d037e71ec3a1d426f05b18b128c41a878da75421e8c8ef3ebd5effd40735c00818eeb1ec63182b44e817403c9f1f6c1a0155334be63a3a15109be6d45ac0d1b1ef5cc99e9b284b00c487d91e5472\nA = 796fba6276fb7129eef2d1572b305f63d7b8c49371cfb3b2c67b141071e66ccdb5e321fa2c1bcf624c77317e2aa135e1137dfa46a34c3ffefa2fa3e316be81f45614d422bf86fe4518c2fdb7e416bec199de033cb5fef7f193a80c0f0e6ee924a12c8f705f5ed3793ab770914924b45cf2578bdd09c701169f0a881e6\nB = 12cf934763127284e642ddc232b1c889cd86617307b6ad72a9fe0d48befd7c5c5370a0062dfbde2add256dc0af850813b22320ceeaeed347eb9319bf22320b2fcadeb51c4bb26a160f7459fc172c27a91d367d5a232d00cf7bb778fba83afb744177bf1ddf45446baa035fcd0065f9b493d92eda37e9138f4fecf3ec55\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3de123bbd50c35805b943e76e97b7e664eb9feb99860750bf97e275029e836217375cc1910c13269ffbd0bd72bb82ca445ccc4b693742a96d19d3dc23f78e5ccbba46d9ff5975f239551c36403ad5fe86997536456c4a5ce54807c24e3b5317b1c7b2a1661aad85b63859d427f0703b460cf72b9acd3f87e2e69d7f8f15e972d\nA = 1d0433d84f1de082d2058475e0168ceb369013a67aa9417f066c29c28272a0b3f8be5ac7190ab78591ae72a1dc8ce628c683281a9ad563e134387b9258b9c96d2df288fc118a8cff068ee49d635343772c2fcc252facdfc93112358414e1734d6948b909b53e46263e9a0cbffa141ef77bc98e7fae8ae2bd85bd875aa7c1\nB = -a31a574d105305e47f4fc00ccea0cdf854556886b524901c22e6f3b59a42915932ab209a8d5da29ab70d1472dd5378d9c79a7447d17665f9d1f1edc1e545e417cb65415cb8a368075c16264f42555d26e83adc704b5c126c6129318a8f394af8bdbb32c8114470d11b2acfe806acdc7b96e1e348a32ff96a988de76d4623\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 770f0c3104c0f3395fabeb75ddfa2c21a111d23438463941239f7c63e4b6e6832b84508ebf3cde1d90cff0a2801beee05cd5118f9a726a987eb58def6780be899b473ea71c697557ff63a4c6db894e9438595acdd98abfb529d75bdf3c1d619d6165a9edb6aaab8ada50b61a3a84de654706a9aedb7321b0523558e8f18116fd\nA = -5fafbd498d610e9f29c38a5c6c262b71672fe9e9c84f0f071b549390353e4fd0101a059b7c547007e27df97761767302458f1936395142ce5776b0959fc5ea039429d64ac5d50c2ae0ee45d60c0c50b7ceb4ff9853d57c6e883f588017ffcaddf5a1aa3e23ab068877a114d9a2cf742f01f5f5d611424c8ec0d082f5c165b1\nB = 552155ef110c126afcb87dd20251220c7a43bd0215ecd22249a21c93583e120ba6f046c6fe03086ef3c97311c4d520110a450470a473d8633e3560d2cb44c25559af07516aff50d6d176e8782c06cd9aadd3354cc695c4ea8dbf85e01dad479c8e8438154351fd5fcc6fc7e9d2162ce2f0179247f756f0b9b34b54be74821c5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2e9ed66317734668c4c354d720a011fc65bb67439b2ac9203dca65a8f567682be40cbad4f55a83e836f1fc135596b624e4327acb085a61b6398237fef5a6e6560b488d4a673b5ae7d734b896d9647d71087621cc81e94d58e01fc2cc2dc775f9ab1b6031840a672fb715b77bd636e3d87b4949ec7bd60721bec8f9907b7c072f\nA = -1a6b046d691830d33eecf2c53953676ed3f6fdd20c2252f6e915052ec28ad1fbf7a5f264acf87ef8ecd515ed921ce6b85017f3d8a8f1d14f269f31e3307c6f935ad468cf012a912b0650a15106fb949cbae7b36c9cd496538bb0646a7a28989dfadc719424519bfa43cd8833d3a748c758f813881d83c98f7cb2a63c2a4d06b8e\nB = -34f87db0f839af6e4c4bf146789db36b3d0bcebb9bad81db690ccc3a35070d8830c9745b2fe730a1f3a252612e7026bf9889169b57b8984a5479cc4cdd6844ee3e150a2e7bf7680eebbef30e0591c895cc8b2ca488d489554f2339e2f55598717ddd8ce444a060cc95cad9eb478491ee8d3b8358c3762a970224abdc1068af0bde\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6455ff7c12bf3bc37120fe3f1302a9916a6ffdae6ee6a37fc23ca2f3a7ad910dc0e1027d4dc304a8eb4eccbcf3c87cf52a13dde472c07e2df2420c1d36bdd5e88c3d76e774ccd2ecaf6a0ef55b8c60231b1348a738f812a4fd9d0c158fd5a9fb19cc7cf9f000860d4cb6509271c8e43ae4193843324db02a029beb58ec2955ad\nA = 54ec203e2ababdb0348135c0679eca2a8e778ed46e53f195331a48d3828e5e40da804ecf95eed819ecefaeb9c5377cc1afb1fb220175990d347981353e7d90637adf8cbb16812af8a3783dd312d967a490f8efe3f23746929cf2a5a8df58e0b878367f6c5e4d3c086f947fc2bf70bfc3a0008a8bb1d7d83f002930640b6ed94c334\nB = 1311b88a05224e15f1465c8da26784dbaeae84f818e029301ea39a982f714c64312f9f02d094c401abb6a89e8537d64c178637364bd261f4a27beeaaa901cc7b3d4e36ebcd9453cda33d47a53c6dd1d121dfb83a222cfd16158eac23482c8abbfaca59e765f6c1fe871d884d281793eb19f6409dd6bbe4083bf762ef24c24f0127613\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 64104f6c06e563ec66de4442d35d88117f2535edf9e012897f44daab5a1b8a8696f84db7a68d64ae24a394debb993bf6734c", - "9df542c7e473b2e497396ce39a064789d5d7b339b65766b002a18096e7fb9f312ea5997c2a85463fbd6fc18f25769ac2a2123ccb0e72f14b0608c4c22add72bda138b83f986e78d5c9da31b15b9d\nA = 145f580c2ebc6c0354ebdfdbb1d3d7fa17f0b55493b0b9a11b71001c840a967dc77f0206c3dde161b5a773a6b5fd9471fa08b205cb6f728e3afba440b55268d6a9542e234ec313d53583c580a391d8da5943f4a900b279ec9d8933f2cfbb260b74ab714a8b9a1af3190d914b6e42212df84f933a237728a5fd5473ce2e272eb82bc83e\nB = -c67f9b9295dd5844307b8fe3cb9c1875257258e4be6229ab097e148c0175ecd0de4d84fe03c8da6e27153c709c2526092b1abc73b5fb40f1d4da9e0f3d8d2fd5f8a4e6f3c30befd80e189b73fbd77e8547b34010d2aa57072db0f00537cf3ced95eb517b23e0c854b4becce128a575a31037c3a9e106a476d8b0277d26dcee435cebedc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 11913c40d577f70a5346ff1cfdca492ff52b640eaf257510d311872c8df7ba9756973da5b9206c6e5254bcbbb4bcfdad5fc4594e41ee44e77f168e2d20a4b228480a9908b102dafddd039ba7f7619eed7057e8af3a72ee491a61dd049bd947e5b09a94ef94d5f336945f47104fddb8493ef22fb648ff5376b68e96c0555d74ca\nA = -5537630b7cfb8daf76d14e617f7b69f7b75b472801a9a818179d83ef2984d0abc8ea4214ed3d3d2bd785060e9c2819e861d0df760fc1daca8340e8a2c997c9ad201d6d2f12a82ae3883cf9f5c51ff1c25277c28175859a7b8e5b6cdec7cb3875071cbe415bb698b85cb19f617162587516f93c728ba8b2cfc19f238e2cfda115b8ec0431\nB = 597296cb27080f33a24241c1e98fdec32f7a4013a7340d367e4cf2a521cd462a2803109c27fcec353a30dd20053a1f744394fed75829e8396f8de434399bafd6cdb6e0ee81343f0cb99ef3087a7c69bd43bd722745a46cdff0c2c837fd87543c3c63df3896ac101a145b478dc224644996fc72460a89beb5741b91a42f2fbaf0d62c099b32\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 42f420adf5c6b32ce53fe23af4e392517e37013b8c3a7d035a93f6ff45142b0b0bd5525cde85f9b7bd9ce219bd3514617e89ef4d9279cb9a3e89e44f1994d72febd23ffbdb0a4f19cb76448199b31c5cc6d7ec1e46fdb67be1211c0ccd93c123d56ac0d9cd2ad11f0c58c713165003495b75b60665047ef80f6a393474cb727f\nA = -1c6ac9565d1950ae6c55025f76e0a040eed0462218e97aea87208ba879acedf413ffd5e63a92dd8658cf5f49d633ce7b126091a55701168ee4932db004dfe8c35c939887fae3a892b0b04d8eb74191bf8fdcf5566b4d3796a5d2596b1e750f64201057ae60aa705edd58aba4b48f6a2e511bf5007a6c44a27e3efd5bf2708f7046c1fff7864\nB = -244f2a90a57e5d066fe22f4d52f91b44882b8ef76d1dafc3387abcb224eda4a2100239e729bbc745237f8129d457e98eafb2ede2f3afb81e63520493da2a5730f1170b31fcac21259e90c894f8bc488c5e5dab2c2635bc7b1ff56c3685607f6fead73a09f83a7a168c4245729ce5b06e482d7d3d72eff33d14cfe2f32f72175484ffa292a9af6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2239459025b257fd0b6659f54b8874f93f07f4d6240f8ad761c9da288cf1537d8bd001eced284bddf78edd611c7f28f1393c6fb879aab6e7df8eefd347d63628b1ae086148f488b01272f67ca19db71a2b284eb17e17aaf1e3e8f23ea253595de474d5cf47c16aecfae360eab7855868b8af361491f6ad96f893f9d3eb66d07d\nA = 558613de283911aea1ee21d6b926f531f778c5226e978ce329860682b5375fe5e5328ae27b00f504f2a2d24470d16c1edcb8e76b4d1a740e55538e79ac7da4b45c5299993513ec3bba7e7395dc829a00d4e228618dd348fbf838eaf0bd50f6c70253fb1c1c734a07d0813915be25d3163df13511f3675022cb85af7646c14ba5d13f615ded8e5\nB = 1f3c3c468146c29408d9207e15b25186d3b06b3fbf9556eff7ed7ef7788032d87ae1a4d2a0983902d4c70936c615d8c9ee26c89af8b58d60231ede54e859763237d5ac59af686300a3e92f456484ce77700557ddc0f93bb40e5d2e5117f2356ac7ffca26dcafb3ce7a5573e07ee97515b6b082fe75fcc9dccd76b4fd416e69a247fab2b30965d9be\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7650985e7c6e5461268867dfa9782cd8154bd6a4bb5857d6555e9d9746ee79b37e44638940bf8d5e974911327f0e53bbcfda0739056bae2248015c35839f35e7e359e93d3a339e7af38c0cb43eac5b41e1406e34cdd4afd458a5d126f70b5d683415b490e0ad61269ffe7ea8972eda6addd447d97e60891e5099ee920e18f233\nA = 184845d3762ad1a9c925c51fabc7b9e15570a84a06ecef994910845d56869264273d75fbb84a31c97c27eb9779e8b39f6829638a78b266326b60546507f65128caaaf36d4e7f85939b75cfb3145e2b1bd8372531cda579f59efa0da9c95a8efc72faf326d35c660b4444627d328bedf50a919029dd164de051a4c0c924103e365cd640b9637d8244\nB = -977390f52af784b52c1d54e82131b072a1c308406e9b82587102e67c6f7145f0020952231a5f0ce9d130677bb5a7a37d5a06dc570a13a29673c8a9068f06242ac438806c37ec46136e7c1c1487ca2d330fc1f3c1f42ea51ba2805b74c44a61fb2fac109710dc3dae78a07057a753898d4e849b910f035bfd807178f0108812778345b256c7b59f8883\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 35d48c3e43070a10dac0e256afb83b219aacc0036f554bd998b9092ce3bf87bb5d3b00947f2c86fd4e7ab830502d15fb2d4e47ead087f5c779a9ba56e272ea86116e2c81345d379dda6b581e9c8f4df8ea56c78f04d4f7412d245e00ac645847af6ae97d5d2ab27e48cc878d8b510c2dc753f6ceb1b9e7bdd923e0e065a6c11e\nA = -76e575cc79d7f0c313a489b255e85d114f3933383cdfe75cfef649f639921eefb9b3b3184351fd0ad252c6e477e153ee586a0ff6da1e1b2bfd7e953e6dd778c849843fa5cc355b31f5529ca45aec81ba67a1e364d5a74a4656d266f7decdd47b2fc2d81d6c298afa2d1c39b5e8eed519a9997a14513537cdcddde0b5b41314476264d59b7d3f0e9a65\nB = 6b7faa437b4e8db8fba56c62eddb8a81e9090d1b6655a2185d656b2db0e85225992297381d653e707aa15f3017880b0f07abf3dc455cb09c4e551b3df3516c6db4ead79b88339fc33dda96bba76ff7c388363c36b67fd5dd0ee63f92f67549dd77e37e9902ae51cb58057579f03286fc48e3b7fba763fc5844c222e6a1eed9e1634d0bd034cff222bf147\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 445039f359b55eec647296fbff4f22beac09cad32cae79c13d591e314fafc2b77839816aa4f641250938865b0a2c30a10e23da71a6dff5985ebf3df4429fe64c327557b12d987ad9e9971f7c7b1e4ad01c94e1e5322dbcbc4707a959a401624619029558fd6f5b14564469b13146f9a2555916491e4d77caa70f51716b299135\nA = -18ddf976fec2090f7d1f4d41b8f875e56c813c04338f595d6e591b3eabf9e105be792f45354ee9beff997e6c0e8ec3fdc714c07b3466ad1a949b9d30da0115f5484c3b9e00c7cf0c117db57c3c6cd7434371c6d9ac7a5da1a0e2d705bacfc22f62785222d59bb5bcd3e3bf2df8e845953c6ddf1b546cb75b1698dc8e20bc611294ff288056723f1e46ec9\nB = -2cbaff39103570df7d85a5673b50fb8818434bbc19ab4e33bcc8289a4047d85de1b7029a5cda3976ab12e1d891b7efe3d5576bcb3713c597771f93532853290068761bea04200fcaf9b05d8553b960ef5e28064de89d9e5097d12b26af0b64beb40b33ff82a55af7c5838b44282917fd4342e2065942c724f3cca515d9142fb8e46652242e8f0ee5ae07b6cb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6727c0d0ecb4a375d0fd1bc52146da1242099d445ed9e87b1fad4daf8369fbeeec49027d88bd98efb425c1e3f73e412fb327680068ae57d4a53992f3759af0ac1b96a92f56c2cf552e6682d1fa90c3910bbc5c0b1754862ee13c5ebd62d5b98bfe8dbbf9bf53bf9ed0b967f3c9da24d4334b9f3f75314b429b05b8e27142623c\nA = 5cb6c49efc6767cf956885690ef740337aa71b90c1d4b9b0a9e4734de0c0c50f2358fd45aeedaca6e1dd0fb510bf097bf46513ee09f3343bbd1c11f507eb61d51ada40c5d6b730561756480063f60caf05141bec9a769c241d367cb92fa8e229ba2e471fc73f48812a25bfc7553c395ca77b80443ccaa82fbb7198f8c35c3b5a2fff977d8b2a29cf9358ee1\nB = 16ff229a0e67a410555dbd4b687f1470ec854ef67db73a902f2d19953c55071c4a26dc320baa8571586f1fd54fa490b0d87dc83e5bf20b78956084275518b307ce69aa4ca1079e3aa753d97fa1cff62e0b5f3b99d96a24e411fc3a3e375", - "ea21b7b35a578a72df68d28286fd9a324c06930905f696424780083715f77961532bad061f3901ed276a9eb6e81ad4b4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6e9947beae4d934253e481d27e854a59c4047eeee4fdc7df7e174a8f045776109c148ba3721685195b8fb59263def88891c5953b5a0ae85fcdbf02abc76f4d3c0f5d9496327d063ce8b3ba875b4f119dcd8beefb3ac884c25955af61c35a69d0670c3c349564e5b84f7df4252d6d3b29d9a75f09e9ef79f0fa9f797bf75b8ccb\nA = 188785951a3befcab56128cb6fb9576bee2412e6cdd7dd1bf5643babae83c8011af99aada405e119c3be33653862440005be994bf37d3802cb6c73cc312824c56841004c8e871ffb560e93a1d222c93d63684e90a91394b9c8ba8cac27b414bf818ee0de7217bc2faf099783800485ce2e93612ce39fc7e2f1db708bf9bb032d92b66159073fecdb2e0257058f\nB = -8dddf094f30284c213577ceb7f1b2efb1e4213a548e6aa840f801cd6382fb6d4995908b7827078dc3f46fccdb9e071bb8531ea8971de0ddbb714d678bb71ba9d961e58cdd5f41b8472146ff9b814a5d1d6368bd94812f8d38f235f39aeb2421a57499fe7102c1ab167df7d33b32a6dc7c8eb8f4babdd6b6c929d1ebd9bf4774aa40cefbf136feda7b6e10ba4dbef1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3f4a8d90017dbe8e77205e65fa7a0875a1ace6f3f215c2974e47dbac779804143da3dbce92db391c2614c078997c7d1a15439ffb51a5787f5bbaf98a4dcef576a6317b9b92dd8141a8fadc05d3be7c150630668e620a4e07b4b00519f34e422610a160de112f1ab8adf09a9169ba95b60242c89196ac6e155021dd84b3054511\nA = -65ff4322f8e46e03aa6c1fd10a207a5e51db6991bdca232c0dbc9d73ba77fc485d881868be7b14c25b05bb59b7f5bb6c4b2a7d53f35d2d7af282a0423285c5de656429ab7d3af7d92837e41ca701f527845e98c2bfcb51647512e6abc6675cec2a7d34ce55ea4dcfe9e7a8397d45a7a3e73bdff06e303a8f04ab6285eeb1bb78b1455931cae203078eaae826a6e5\nB = 4d936b603eba3aeec3d3f1f9acff02a0ecc28a8ec64b6bfd9b153b1bbacf4f1e186d3deda8c1c81e759237921cec53251250e3e838f5063c4a1eb6cc93637f35aca10b965533d18b713617a312e74c446d63eccee93cc97e3723ab27357ae9b3cbfcb3e2bfc589a1bd582480e776198df047c3ad85f611ca6fa480c70aeb98af02f57d56dc9659b2a6bee222dc3e0566\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8a7f3cde3230af1f1fc25e0c0e9ebeb69161d3864fa5a03e5d7f8c82d9940ded285df35c008f61cc151b4578e2677b2f2cff3236935de5bb1d113597eee448496fe29bb18343687f6e9f1c783863e949a0954de2993d47a03607423b458bfd18c844ab57e9e2a43930df159ce8564edb5a2a37a06425626502e3ff9363b73c79\nA = -100f2984dc1451fd7b71e5d290e4b7de2d26175a47b9bed524fae02bd5abf96faba06e955107329559bff3805689633a4a57275732bc42183acdc792cbf7b6b24dbdc8921b73c0308d0c0ce5d8aad75f7eb16352e67116e859b323deccfe5d9ffdd1f0265297bc9eede073146a06acc3c330458b07b8fd0bb652c7325cafdcfa165f69cd0de8b145d49ddd576fdde15\nB = -21ac4953e54347a56800d75f6feb6ad660b0442174cf3c5dcbcf6528e2b5da95a614d3a8399da14507df4b8eacaddcddd627b10ec2dc5fb8c43d96a38e6dff37189ba275afb9484df800587f4953e327af71dbd58780bd5885b4cdab15ea0f2864f961bbfa9bba6b2d9448443af87c0cf178990254c1ae6e19003b1621f3240a6e5d0a3be2deb5dd253f5e1f88dbb60b522\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 76f8b44df8d8547f8b3d8537393d2805c699eb37d19bd115bd5539adb6b6a00d004def3b7793d5c71e0ccd2b7e9fb87103c1a5f56a8f18ede1bfe1607a346297166596aa78dc584c7c32832e11b72fb4f2d40ae1591f341919bc0157080ee8febb7fee5461a918d2178fa407c37a8243e24206ce2c19c3addcc2b7c3c1912b6e\nA = 56f4d397530f5c90203df1ec799f82a0096888fd370d543e33b5a2c8042108bb75a86265204c40fa5a9a44965ad2fb41896b134ea56c79699a230f38c0e3fa4e5d346cda70e0253b9993c9da5642f4e645a0d96cb732f8f04c99a83d1f1360a385c6e1a972b89915489245ce58830788ce23b9e62d6b48a7ff9a486614d6979033f7914a0735d201c6f29e512374088db\nB = 10fe818f6af7a95cfefb0ea0726f9a3e0e7c30dc9785b1fdf6e2b810515448386c7efc656479794d389e109ef3efe37fa6124c5a7db3164268da0d98538606c57bd2f7df9482860e81f272a27c727d7d81a66fc1a9bc8c385cf02b7ca6bc7ec2d8d6ba1dc992caa216d02c9bf0fba8ee754af77567c6e275ac1b6b1b36b065760761300d156e40da8445712b8fb206c0df346a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = f580f9d2438b22700c3ebb23d1dc296f3d33deae2d32dea51c7ed3a0ce7b06af11046bc1cc279bb744bc31e7f822c17ffcc5dcbbdabe213bf97bb85c7e19ee71a513bf59b25b3b5787e42e9f3ef6aa1acb8705d69924a107b4f88e0cf9276c2c7c47fa4bf56c4900b557aa5587418f0ddd899630ad3ff678b5b907c07247b2b\nA = 1017a4fdce8bf41ce804b7c9c836d85ff6ee899807e1736bf0357b015b701b9675297e5ebf588ac6c295feed3c6a367987e192be0d89523ac7d64b0b9576f311b5b2705c5398276a52f06085027480c2ca72884ad7be34967bcc6c8cb4ec4fb761e88c16866a2e284b40180eb14536810eeeb180ab701ec47ece62af65a0753f95ca657e7d04ebf3c3a7db02993da9089840\nB = -aeb03379fcd4e87cfd18957a72fce42e016951a72b673a9e81f666b3cb20d2bba81400ecc2b38601bc3270eac46a633a1a6b55c50f00e9d7fc8a20176b93e971cfaa4f41573b17b8ccc498f8a3230825afd0d7f102daee347a9d59cc0914ac8689c1d8b39ccef1f3def44054307a7cb7706535f0cf4007231ba21696424c3d5b42c8e85c278f7c2e8b7d1787effa601ad357eeff\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = be05efeee19cc91e30a9277a6551aaea63aa3861b63f6061efbb0b92296e09f4709529eb849d9f40406fc59c526a4697144cef9661b556040458940ffd6a87ed56cb073d2ee0e6d1f05936fddd1b9a8974a3088577847ddde6bbdfb3d69158d5b3899c13ec78fb5cb6aa7204efe308bbe0b52f18381fe838536707a8a27ba0d\nA = -669660e75eae9930dcbdb99c477c980869417ec9c0e8c4053f0bd8ae62d496daf7539f37af96fd1cfcf3149bc02b8182a46b413e3397b49d4b4d204491440eea65505cf5d33a8e797af08f3da41f5a0804214846bd95d730260c6545d51126278181719ddd396c55f119e84da71f0683eb6db8393b098b3a0c5999862644e073b4918b5c8aff17efe860744d85bc94b582d45c\nB = 6045f903a750b69b709cfd6a1c8ec9fc0d7da9c53a9d26fdb0ce9a17c6a0ed5ba633d6fc01f004f4a48cf247d61f7df609008ca5bdc8eafe06dcfa06bb67efa6a584b5a2f02768718a908978edd475a2d2926af2a6e523549a5cbecedc78323c5c295bc0b8d3e14053078492e82e339ea2c6301412a5dd7efc20da0aad0577a37d853eed820776e672bc6d23dc821b5855eabcceb18\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 705bf20b7d92e68a69019cfd721b27373c7ff22f911066907f556321371fba70dbcb9774d3a26ca43e44ab20c586a3c1546fc3152ce011be66e04a59c6631bc8bde18efb7bf1743b9ed75a7a6c5bf5a4117368b81b112a3cd4e1c44a621f534a11c426451ea5fde880939ee5bb28d9843730e284520a976cd9f60c94751050ec\nA = -17c1dbc1ad1d2d33dfe1af7b4cdc7b69fefec5a92656957e111aac292e44719c7c752ace33dc74a6568be38b576a5ba174bcba77a034af5fe101699c99ca39f8a3b0a20679e6d0180868a232fd8fc775089e185e5eb81585403f32619a2f4d857bb091a824a89de2e84529e5b0702b45771a5816c5a823d81ddc89f8a70cc3d3a0c6bd6d85e9d72b69d2713b61c46161f7f4700bf\nB = -2252b54c602456c5deb86a0f249f3982c3836b70a946f636b22fe00c6e3b91b94e19200a33087fe734ce9a3f92a6099ad03a95ca523b7edb9e1ed3464d38fb96c470464e1c54790cd48769677efc5e1d22f5be4c15288bc5ea1dc184a05fddd5e576b3b4962f37437b4f9709dcec374377db44c8ba1d8611c0c3ec35f9bba213eac59a047e78195ebbbeff941c7f862e8c80eafb72b1e8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee", - "199bc20d30af280fb\n\nModMul = 7306e3172929c00c29ca1db360eb4ce82066f237e9cf6aae368d1f531620e9b61eb64f5b3e2b735a3b565587d7e955d052df94a20e4aaabe493dba2c18e85fcfb65df166cc48733632d165129b112598bf5e4c58dff662e558e5f71b25f36708d3ab6536b1cbdb5aa2ee56d9e019a9c3629185b188af909831629ffceab634fc\nA = 6b31ef80767a7693e7d0a9ecce54beaf5848120f036923d80b7a0245aa6a46135e32314f3b227268e0bfa1f45b4dce83bea890526c7ac3efdc8e485189ce2c51597c2864c2d3664584be23559c03670622a53edc2c17b3f1a92640078ec35189dd7953e55e4da0290ff1e2996d164d69f1bbe6f5285ae89209d611a7d760e413e23285066eab8e126c320bb6130a91d67ef26d4dabd\nB = 183f06828033287497322b05ac08f62dcc5fa67b7a10c6c5a319c9a1e642754230c6d9809dcfd2de4bb9e360d6e6e1180f6ec6e0d4c6185e34ed299b6171e653521d0f7b8975ed5e7d2c51d27f9784a4b6f9b5e97379fcdb42e4df981462cd5bb9d0501f93f217d954f6baf70343ec710065eacbd2b778430ddc36a7ef0515f29d5fe78d8708d8ffb6c3391c6f632cb1bacb4ec52972ce0a5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 361ce44d153f4d251952c0b90681a19b7d2d8df7a6c5d459691a80c06107b2e818f93f30f8dad352d2dd87b01530d51fd1c67cede9b1a6167697098e41bdc5dc5e7a3c310116aed0c7b5fd99dfcdb3517c13daaba6ad10879f600eab846cdc110d392d9bdc0e8ab34b317840a725a7a12ceb48c75e8dfeffe2947aa85b2a5158\nA = 1e1f2e44bc7c79a00afc3b2570d5cd27ad5ec9f45aa94f63f2ec3fa6b69077480212a1cbde25ded7ab1c6cb1ec26d5905948e5c1d6d109bd5047b1e038666054606b42e880b609f6f00a219dcfb504d481d6fe709f4362940f6c4b6f2e05d243722cb32bee5508ec94eeebb53b5befa551d3ab5dff9cba3daebdbc97179e56cb778aefdda6a0c24265728ff9e59ca3c2d615398d97e66d\nB = -e018708df037aa2918850fabcad82731487fb812213b1c067d0688462a4d518e5ec7c4c84f2cb2017aa6bc960e2faabbe361ad8f66355366cae869d366f06d7cc32ea08dc51631e7f36a4c775611095d8aed06a0086d0a471749246d7157947a1eb5d5503f207723a7062382b3e45bb84c6f555e48f6d63aaa1c04fe13c0108507c0ced669a5296bcc16debf18e03c32eefd177bbc1dd2f19cd\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3aeb3ff6e797d271fd2271499a740a91569f300d7392a7b5898084012a3c5ad379a57d5169e43089cd58fc7210314758d5368dabca2f0ec5cf6786801bc99b45cd60403c732d9f98936aed76da724bd3e7d4b622dc690778f11fb0310fd4cd980b220627f7a864e107f93a6259081c6581e5dddba4890508af8057c1af29a745\nA = -75e06b47f60edd23148c3736c9c125a617beea7c8fd47e662c9d9be883ae925b7801a0030df3f4bdd3c9fc386f18c4e002e5daf4a6f7fa27b2f71252c83d5f1695e50d62a10b99e1900987b342290decf681a064f789e11bc3fd75d64e2e78ace56e7491fbe0eddd6f9958a5f95775c920ad6c051ebe7750fa76891ab00f42c910550a42bbc1c1e5aea0ae13b7e6f916a5d228bd57e854f7\nB = 434c8e4767d0d7df2125def75a978bb1509a26bf8305cd03df748c6c12b6dc580a2c1ca9a4526eaf3936fbc4ec797d0733217a54ffc9e1d7c6ca04fb39679859d5bd3fa64cd0a09cf1a056094b9c20ddf1f00e134533ba9892c2ca7346ac8d0655250eb45df9f0b7983bbf71102c6f1a2d9497e7a45eea7b3095cac037b7aa755beeea8a6191da268780179a652d94a732a2a5c7b626c0de3145f4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 734a429c91f5b0f06fd47725ded06222c0193dd407e9daf136696f203e153c9bf6df59016849284cef93fbd35edef2cd31c9b956fbe562d2a22100f177254144718ac7d22c99783fd523b642984794bd7beb0d0b363e28d3f3469ee332ee364faaafef25c1d4a11b5e517e44a412ba717a113ea9e1e8f2d6db8fad6f10d06950\nA = -18dcd213e9938fe4b6a64abee3b9867f65e47e5b0365d45a8dee14ddf787f34072ce32f38d4d48ccad236005a23c5fcdc02b72cf27001495663fc56f428072d3f1bf5e33ab2c5f9dd9facf122f7225ea03c2f67321530a642803f65a2e9428f32d0d974e68a25f705e4f8140568f7e4b132942b49f9ff53f04f241feaa29aa353925fcade33a0cc192fee2628c2111da1e652cace9d304d0f1d\nB = -2e5397658a5e6db9d30f09e93e67a30dc84b1e17c25786e041fca48ab710e1d0497ce615264f1abcb23d5aae8412b58430bd801775acdce06cd362438898697940712062b611c92ae6ad10da31784207c5e7b9362b20d7254da0df8caafe0736002dd466d76b1a03e91a8dbe8a71107abd5f07b00fcdca2017391c7c3263881a3d02a89b0e16a2a765a32d24ae6584cf44a88975c539402db9a301dca\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 427609751f28edb62c717bd98ddf999cfcf65128b652be1b5aac0dfe1bc0f7687c580ec70c8290455a9448c69dcb550c0cfdd109af561ece2ec8707c1d02e8097e780f32ddd932e706f81f68711acda0e7610f4dd0fd55f6ac7ca3a3184f655b0b29d2d62974739b43ded96b413b9e3f0033ca1edace24b6bb610bf06b5d940a\nA = 6576c31d48daaf7d6bc3658952c4ba18095f1a0d73726f6fe59381af45a2a6b592adc79fbc3b597e1eea711ab295cd991441fb5fc4ce5f047e571a7d949c709e0d31156184be4b8a6a49691ef93d7d3b120193f6ee82246aeb896b8b7b4c74c27c02cb39fe0335883a3f088a71ab42b947a0cd59dd2155c65a0274ec0836bb8c2fe394500724ef84d869bee40291363389e7012d672b1eab6696b\nB = 1ba2888f30be283b588cddf00eb3ae3c641e35fc0bb3a9fc85d7fac1e81052129f499afd3e8458d4cf893d51fe4a2bcddf70f28c8edef16c7bbfb791daedf1a8248faebe36953560498af652d1f1c7aa0e9a5a667d9c94f7d9525cbd5a82147d58b738dfbba5aa162858c2c66d0dd7d8db38d41a2261e6efc7d0c8b2dd2d6962be0fc796705cec8e87a13092e4a3febdda3d4dbed9d11a1d5f92d7dafcd6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 533d6d8d7384e6e65569ba0daae0a8cffbec1d20e417a6edb42d401a59de0a91a7e6854db081ce33b76faa63f6d866993c245e69ddbe6c86d339f7107a4807856cbca23cee2bf5496388ae8fd8d7c78767d0775acd7bd6202dd75451b424034e2766185969b5663b638d539f718e50a9f752f406c224c000bf1ae1fdd60a2a82\nA = 111940235b144a42a13201a41a3f9e4ff02948f8e9127d9a3007906988a50b36d7622d1221155f2516812074a7888b1d8334a01c02ee33b3164d761d02b36729c299ce2455a462bf18471fca42e5b01615d53723c3fefa5aaf4a039a6caad35c348a0a4dd3f0204f084f35c0b93ab233c4066dc50c5fd3897a769a7c5bf309f7a9c30e905466c8394d509b79d62a69b58c73d8d3f1665ecd9a8a4dd5\nB = -e2633e43c38c0b4b8713c20bf4e2b8ccba680ecfc1139954fc42724277beadea438596942fea1094091671c2060dfccd0351b2fba8cbed35dc963cc18f8e8835052da884799d88ec1887712000a0726b17cbc4302421011d5be8d234440eecc363f09e2c04bc9cded3cbbac9a5bdf0b6d418822fdd90dead20e5bbbb3566ca94ab85f3a00d32842eee6521edd18b9aa6872340b2f47deb961f58bf231e01f9\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 33960d7ceac73f342d46275e04fed56563decf2fa4c0e9307c90288e911ac8782f8e1354fb051a9da8e2db83d7c710b5d2b611495e72ed42259ce783a7e7a8f601c07061ec749481d39a082f29dda1f9c7f444a33ae1c1055d37a677b848af371cd3bd41c851d31a07e144d7add66df39576b8200a8b918201630b3da8e664c3\nA = -402034484e499a8efd610200790d443c5d3be35d19d8808da85954d42dca3f24177de48f55fa2efd7e4f7f624d806a8d461c3bbe0b626fa1f3cad2145746464108b367b13f3537ff395262256bfccce5f0414e1f98b59ed29940171d46ebc4bfa1a27802cc30d9221cfbceeb92abdfa6e84ab4a54965568aa10ea631e82067ae358a1a93a3a3fe3a5ed5636a0c4cb373b4d49f46f8fbbaa665a19200b7\nB = 78ec7dbfa2b28e268619ba6db34a23adab25e7f8690aa9464a7d8fb7c6b87d5dd9d33d4c023bb665f2d96febf2638fc087ed30796fe7517fd58e4120c0d319688e67a32bbeaf62a987a9764be75384bd499b0e00a850f27e303f615031299c631844d10abc571f9f2a0f742cc0e8df2fe3c244bd825bf1d9134b2f1059e2a1b61985ae8daf9bfbd9eb24ba268ca58553891945ff1a314a78fdebb5444677ac081\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3a1ea3fccd6f336e6d444d68af1753b83145131954c20f1e3c433a8", - "9eeb7e267425a34d91f67fd65191dce85769ece2fc7ab12d032f3e30f8509095ecc05148e47a85391b21a18257c338a6a3ca9816987abc8143fe443342b34afd8a52fff00dda2e42b1b39322bd38c6a1f711051f791d6cad2a47ebd423a9b933485fd5861\nA = -1869c53f86755aa350115a9f49d6248cedd42a339506b8ff59cb878b7745956f142fc4387322c41f369773ed375b72665026771d4ed1b9ece08f84e4782d4c3b0177853cf9ac3a55f7e52f39c1b82aa42b30628a4fa6a838754ec6ff9809308f675e455bca6f44e298394888d85fee29d8a0c8e9cdb9aa08d68cd70e13a243b5804a3ec199f52ccd462ba6594d856602cf1d5efa509047633923d31f78da3\nB = -2023c544b6cdd8d971bbb345300f7a101f6dd44dede6bfb5f4e6b4eafb7a40728a3063f6d4bdd0f606ddecf062828cf889b2f632d0c9254c28f36dd974aef116b73cabeb2bba98635841c2b4d2aea833e35eb1db9fa9a9d33bf7b51c49a14907dbc6036b027a039192b47406bcc56bccf375fbdf40b82ac4b3c660a43d5a6eb656868d383cebd099d2a73506f675cf29649617fe06097a46de93c13d1e590ef2cc71\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4331f18a94c169cf0253136bc4eb7480c9fa4401c18db1194371dd53e5f7b75f07ec2e1e1c4116a5d2a8b2cded4b22925b67a88af9b8479c6e821d58cec7ed9f780a4c41e729982cb33f69b87d01c11cb9a8f7952db1920b6eb2124fd5d820555a99327117d7e8e26d18e748fea3ebc17e1d07161fda57a21a70c7f4e251612c\nA = 5e7d4ef7d6ace6cb106e38d96085d3f3505983fd952498af3c1d9b2af61e4ba10e14961b339c6e64e11ac758d5fa18c3222138290866970d67d0a4f4e19f453503eb8dfb85b44d1050c86943e7c5d6faf7851bedf7d0cb6b13d2acee25372243591d37dd230907457fb440f83b62395f80f59a2d02b87134887406a78efd77614f3193e517f234434ab3be084f1484d3f2c1f68c67c0d6e863585a8a5ddd0be\nB = 114b6e6726433ea88a2ba965f0881beb3ff4d377526e4e099741f069abfaf29e129a1f5fd243c6599f725a389728f755f9cad767ca1d6ae5c8b3a32102e47af211e86d67574bddfa42b2cb466d968f38b47333b1b55211fd9a315acd5ef62cfd3e83c13ee9d3fa20a06b2292177961dddc7dc39abad9ea31ead1fedd3d699f651b656edceebb0bace11bebd0cfa581dad577b8b42f0a844bcd8c8227880876dd7b0aad1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2468cdb1a26eaee34db3d2724e37f023c8a1788526b3dca99321b574685cc8303c609c85401a58fe6da181daf4111fe8c6d4b7428b1cd301cdb9bf8cb6f33140756c8b490d3b2e538ff294fd6471c4d17b9d9e4adeae0df088cb9daee18e825a368be57af4a096056b9e76b94c8d3b911b6a074ed41082926773a585007752ce\nA = 1e6a59efe0b14fa017c32ffd0962700fa9752242b06ffd0b604b9bfd125114d4e0909534ede704cdf1c9e88a6567f4a2989df752510d087d7b7afb515ad594627ece54b8a8e539074386121c9a3e1c12eb2641ded8719e56d42ef50e2f3b5d7d59f8a6f897174cc00a7449d2b91f33e9df07902a95479731a44fc4ebe8048c449bd515ef6cffed70ae78c832cd43491203a247fcfe0a403862266777947fc2542a\nB = -8a9d3646831dcc852fecc8e2335549e8baa2e2d82fcb90846ee82bcc715c716d4a9f62be29d5e1531db73c2186a4d2f118266de33d966b78f989600d772ffc55b1364117d6750cef67f4bae851e7e3f8fbdae7b79de7eab54cc1fee56e25d0632b2929e352c882ce78fd64dd0a1473e80b6572f0d4eb67f6bd6e45c7617314219d6f7de5e505a9b395096cd36650d23e8d57d6abfa9faaf0ddbff90d32865bf5ddddcaf28\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2909d3aef7a21244efc9b5b16626e260907ac11f3d00647f2170ba37197e47b9767030195c2f6d5eda717a83a152141bffed2e26777417ecd8e27aed8666698c2e85a414dddd52b07b52b0da7e08b3217fa6a331f84820d21086a4424974e1e8cfed3501eb054242a9f8bf0803a94981b7b81776eca6d07cd50c050dddf81d68\nA = -73ecc8a6a1507fb5dad40677dc6ec75f0d130ea704d1e87b00d2bd56a6be21714bb30202739170b8dd3605f0553ff57439051efea2a97def70a6d2cc3fa2b9ec27a00c1338bbd588513f0f320272b8933fdf6635e585d1e79203efb5c95a454fcd7f33aa2aeac08902107e9bfb29587ce8610d50cdb7f2033c5b726742fa9f7f20b4780cf9244e6abf6b812171a64b870c3ca4c9e898d4c15e9f5b0194ae736c3783\nB = 4049ae926bb52e862606842bbcb4a5148bd1063b6a56f331cf10000c524b4aaa80b3bd914cd697ebc98d68bd3c2bd5c87fac4ec68606c264c56e25b19d118dc9f2eca19bebca07269714f2955e107b3fbf85530b1fe99c42d33031958280b8e8abea5a918a41cc7e6980149ad68fbf1c0041798d2046d7f88a395348b295858c61c2f33d8512b6fe75aa8fbad62e2f9b0b7876ef95af8a7b7338a2d6b25ec6355c276fc6ce23\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 22407e4fe280ff5a10eaf46d8e1f5a1e77a07410cba4106466d703b11764c60124fa355733b47327e952a12869476306926cabbd797fc80b4a6dedfbec0b7718ee754d447825cc405a98b85f1e09ebb9294c4a4636aebfc61af4545b921cbe759d3f389beece3f29c2c7c07691a4c46a1a72ce418a239fdec80df48732627866\nA = -1e165ca7e1eabd2ad1264d5ed9c3d2b687f2db5b507a0e4d21d9e042cd46e93c2444c6aea8491b5caba2d8146bac656b7754b7b1ae0f6216029c7167fd3b1c3ba2e20469d386d8566ebbc05cb51bf1f1eb2cad9dc4fa454b07cc1bcdb9b8f5a43e354c4e0f4e62d52798f667080a0e0a15414391269fe8c92f06da74f6209a3b215adafa1eb6866f8b3e419468e2e5b4db0d0ada80514249320cecf034477977bcceb91\nB = -3f314681eaa4cb41a3feae8467f7d76b8b05939731fdfc943235aa4d67bdca30e64de541d17a8971e829bc0159384643672bdffbc93b3eaded7844d824604f46aa58b1f1b9d788106aff53438954af015a0387268266a6ba262e2fe7a4c51b5af6ff7f918674b7407ce8282f66e84fd2582edd809b465e4401c67e5faaa9e5748c06e3bb8ddb23fa649ccaf9657dbf79b937eb8959aae8d5bd9513c1e601c0e536cf60c4fc3802d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 385ba217033463cd9cb882fe30373c2d8e8475dee54aba1ca9713a709f40844905c2544ad792784cc8eafbb412dd68de6f98522dfca1c3de8e3bf4cbd09bee4656c4341153b17c98f9ac09411d16ec9880835cae772bdd8eee51eaba7c02ca6a1034c2c5d2d48e7ae3eb0e22f59bf69537ab6f1e49e58a71c64b8934113eb069\nA = 5137226623f4ce4dc9b80a783777ef4e53ad3c2ec648264db472c517a96383ba1173e52c2659a97ce36341a11e832f4ad293b89696f91a051c35bb1db6182260d4a276d1a9b4be848c206899f87a361d318d38b4073a7470c5743b816cbbc3bc1b20dfd7971b11ad4e20d947e352d42760104a5a3cc590b985ee3b5e98c779e38d2581413a2208d31873f9644ec979602671c9da72fa6f66c603c1bb6d8e690dba8bf4933\nB = 13b45d4105e3f5e8e0ba36c812faeafccea2f1a30e2ce8ffad57ffe0dadeae3a23e813758f270423ecda3da083b42432eead7f04842db8865f9f1e2226a3d298ec1895ae69adc55d1d338c3fb787f0676664564eefe46ca95206e81678cf1a2f173c52d809b1e06641a9b467f191ea09fcdc597271eb43da1a9a856784972ce0eeedd49ad363dee882438f09863ba5af063925871c525c6c0ffdca428054e039e149a424c6d1b5b2b4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7865f718cb30026837ca006f5cd997c5b917726ac6d9bd8c3fb9eabda0854d528d6cfc10e4cd3f93f6848582690c6a83955072daefc6959d33192fcf42a111650e50776ba9ae43d3d26e0ef2c6b60c3871aec33eda8c56353903e7ae96592fbf350b88d2f56e03f7f327022a2aa9b7c484a000135b85bbaba6f8836cbfc81901\nA = 16978c06a03276fa2e0bea45740a98d55fccc9d27321fd0a5b8522298a2a90d391c06c5c59e7eca85efeb9b4c91d4a1e9178adf816d597311f004ef98d209b59a2d4b901fa14c57b7297861ee58b89c9b2e931e4ce5818dd4006f3c40168bb4d3dbbd059c1f1cc24ecdc64d37df16b8e8d0529247c06f905ca88a5d283ca1b9e6856fbe8115a326061905b369791772a47900974339722d19b3aac16a0bedd93e1e4e4289bb8\nB = -de6dad276dcc0a9e271ad523620ec570fe6e3b350b934932ebbe36dd571edcde968b6590be14326e0f6394c0a2172052ff8dbc3ff15d94fb6e36a098286333768a84fd0404dfa354173d01f98484fb20897c439c48952b7f1791209fed94e9e72bfb3df5f368d420d587ae8bf036db6700f77b130459e9de2a541ed885c69c5641defa9436a4f7a69d2848d0e5d1074f77fa688b6dcc4d4c7de25a3b1b040546ef7f418112127cff173b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd99", - "13b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2d3dfd14e7ec60f842d1db83e29a0f6b052990fe8900887dc44476ed3948870c57e72e91e1941c476baa6aa86f76dd8ab6e6ea41707242c46d39b54215bebdb1f28e59d719fde18bea9994610214ea68ad9f2da24e1ad8a06f8bc698f8e76379ff332a2745af472d52a4b8e57d60280e19f93d5be669e0832824321e9ad8e76b\nA = -5144d5ca834f7bbb35d3fb95818c1f89ebe08efdffd35993a7691c05aa1b67f6a28e219b27fdcb66e516097c9ef5f00e4257c561b1f94c52c577471cfcd7a55314d3b0fa308b59449a36adc884c48ef5f34753bea746bd6fab2f20b86814c9fe50e8abaab742916313a50e3c390c67fda8e3729ee3329dc5e4b7d3107083aa3a07daf7952ebbcfea15fae7338cd0b114e9ab2f81dc2e80f90abff7a7ac59e3aecf76fab87633ec\nB = 48b927a46dbc4e23d714b256084fdc7cb9d4c96a988a71c956e0bf98785ebc9bf22b9d5c6ba0c419e60afbef7b96cc0c4a13e397aa2d2dd7995875d2ccb127169423455d138131199a263151f28d232ff4ae24e316907ace1fedd02a02cb5ff9c831de33e6702010fee2232bbe3c1c193ce792eadcad0c81e7d7c17e49168377b68690bc61f22dfddb17d82a3b993804726037cfac8aabe8548befc52a3c6c6baaec89a392133cd9c45b1b5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3f66970f600a9d09d73fd1ff813e977f539d69fe1784b8a2f99506d868418e4b47338ee0cbceed555f88824f98ffed39befb69e8907a5822ef7cd2a9950a070aec8fe4db9d68e1c0620f9eab4ab529c7e69466e325fe1c6c011bf7ab62bfd1a136597d7d5c47e8eb161ea048477bedc88fa30e4f7ddab2cfeec3fd0bb3fb61a3\nA = -1343c391be3f2b72c4b79d8d6091389c9602e97774b18eabeaae81fc0539336cd8c899341cf75fa758421c7f32eba9df474c934642003408b32db66cfa92e6e414b42b1d49c7e655ffb4c80f5bbff8d2774ee4f7198839680175e1ffec0428939653c6697eb3681d0f92634cab1cabc63f423d5a71d65fc7150aaeea74f9e0153923a1c65dee4a165e6a01a88655fbecd2db7697f4d2b49fca2508e2b8f84129785d36d88bcf59f4e\nB = -225a0a4afdde6f6450f28736c3ef6e67d67ec6206a63b11763bc6e69b03f1494b275ac504868caa6d56d684a12dc1098ab0d030583e73a2f45a42b8607c0f19031b9c5f07fb71919868911806d210d43aaaced5894e844881e89bab85a203af9ec3adb105e50b4250343ca50c26df14c46d73a22c2e4804d26d44ff0bbcc13d0dc7e326c9e4eb441f493c9743ae0eea0de045e05d19ac32d2379196a165e63ba640ca42e4861caa24c29cbfabc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 54e95e86e87bc220c8f53f8485402327885be34e34063a1b81e52a23fc3056758cea1c039ac4e513f70ed9d394f5806fb771dca8e342368184e674e6296b9a705c6380bdaf11550cffc73f9f55b9385c85fb648f105f11138a3e1f9dc0a39a0f9755f8328701484d45784e3e4b2ebddb32c9d9132867c6513201116428b791cf\nA = 5f1239e0b5dbfefaba906bfd9003336489ffdf634333cec2484c582dbc19b66782ba40942d047c3749597ec4d89ef61b7803d33a9842f0c903461be37c679ca213aea894d36c1e12bbcaa1c679599d2adda9bd23e712dd0d0bd3f91d146e7a04f3e7ddec8b0db7e12377ab32ba241ed1e01da070c1f3ec85efd8387a7b9421453969ecba8cbdeeeaae6ddb098084bcd250601af780960c32f0a1ad7d7e61fb19f40dff1060c5f332830\nB = 1113f145de014bb6dd6ca05de159b97e9736c45bd3bbd8477f739daf79615fe329ce948cab9787838d7daf797218af5ba7925685ea341b802690bc9588ba3e916145cd3ae9d0c4a149637b890cf50fdfa8f89a62e508eec68f9332787733aacdd57ec1f359ff7fde76138d5b33d32e64cf7d252f2bcff14be3adb1afd8da9dc930f5261e6d715ac75752b29f083bb1de7b0b89ddba633b8137f3fd299a7f77abf79781a10d897e7bf2c958a097227\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6e0160eaac8e1c31cd3cb6c5fb91ba086d033b4b69e41dfffce7569e61770f6629f23e12f0074c47c46653bbba94701ca798e1a242f7c4e25708d3acb5af6ea307b95cfa220f8879cb4cfff96b843d6eeed2b15c8f1bb21bb2b511cefbad0618d49d9ba33cade6da6ab3b846a6a24e35fb36d41201d3b85be831522b9bf509e0\nA = 14f4e24627c773527ed2243c0d1947395aba5c9cf95ae62a48827ffc1477614ad9c7aaea4b4fdd97e3272d3e220601565aebf87928c301656e9edb08d6e680de845615bb3a81c61ed043adb9d708ec1447f057087211673fa6ad8977166a2b4a8079a4f29d48e7fdd6875ccad05d2c219922b814589996cd9642ea2b798197407acd274da30d3ca008fefb40a25b38cb6042a581393283d6448cc69df9a5dc2b0777052566a8608a1010d7\nB = -b4188ebc5bf3ba31cf7c5e100e79806e92ff6f863c3d68a66aeb3ae8385f596dabe6f627f3812d0f2baea319d93ae00de41ab65e42eae7d396cc8fd0a2dfd35f303117fde4db5e8438df0c2b3b680dca538b42a7c844a9bf0d3697fc89ad0a73594627578dabdc214e0f4aa06b40987aed473e7f42d318bebf7392d9c898b4b8d73a94726aef65807b2ff746d4a9aa76303ed7b4fefbab34f5c87c2df82d20457f68289f7b96dbeab581294974e322c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8dd91f390c1f85f153f332de17e5de82979755d835398cdf3dbda1ee73c68f8e7565a964ae33fd5b1f1060572bb3af67eec79c4c3e2eb4de118d471f74351b80a5dcafc682bc3cfde642e611ac1d5bc2c49b308c30985b1161c4d78cf7621b503e2dfaceed886befc004f3a729b4a9bcbb8f13791d973bf38fb8101d6b7a4d4d\nA = -70e99398673324ee83495aa0aadfffd7bb9c94ee5251fff365124fabc50175d794fa84509f034c2b86d83607789338b0eebdbbf709a129a0ed0afd21c130d94b279c56f1c7c1eacfc6cd13f724a9352b2b37412242a47b23ec61ef0040a8855371aaf238003c45ab9d18a66cc7dab9653b93c323815e5404762d3f964d4654a6995af507bb2db2149eea59acd72af4d034217eaec0be5ba1d23890081a6a234e125572e3bcf68a6ea52d9437\nB = 661d8832671a4974b493e5d71e547cd46b36730f4017e50c5d1a7520fbb75f0314cbc2ac948744dd494d566ba580a2108106b120a797cfeb1fbfdefdab6bd6b2e073f90c77e814cafd0b7f79afeecd59778b1dfee3446fb32139b2311011576674f96f151f896b477c631237995e11e61e715dd8dd38e802af93124c66eee735c472972000cb4788b26752a630ba63b45e8ebbd979f0a4da5b359abd2905f0b7f3a21b1d381cd02ac08e284218ce41c907\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b591d2c57f6a5484b43cd7ca247c48a1b38319e843257331c8807d499c7763de4eefed529e70d4c144e5e843ac00ee8d106d0d82163cfb7afe528a7daad8e7ed105942d1128a67e38d59325cffc0c3dab9185247e0082e3ccca82a900d917c9bd0f892d4b518a752f8e9d38eab2acaf3b3b59f15b0fe4cb9a3dabe6e0191493\nA = -1896f67485a740720e23e1642ef02742ce5f10a92e51af19e112cc99c0fbddb60d7190086c942d293d076b474d056e74ec9f0c42055d745a57ba370c51ab2b761d889b766cec909811e2b2fd11d6916b753ae00622f038a4bc55b813a5d06e6ac136e81689407de721ee852cd21ea989ea7c8cbd00b64614caf0974a62097b2eb865f46fdb0c1a2e4f2d839066b797e51392e5ebd14dd92630c070acb546dc7438631fef01594878643a4cf77f6\nB = -3a8e2f3b8378a2605f5affa21c4fadcc655f2f8357a3427d2cec0118e55fc2bbc25931259e294d91bde8dcbacd39e6cbc125683da7d0dcbbc67d7c5866f08e7c4732cd4384d9366868370ea40a75beb23b81306303da4a3e26ad357c5c743d0a4ae775a472afddf8f21cb4a1a3350bb6aa71037607c334a0c79468668d3e727cf1d0610e49f27780901c68aecf1d145953e45f5b090855be714cb39aba2efb0f7db2786b331dd9bb8843de8c73c95ab13b6b1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f53bdd643b5b22445e2af3667a93de52f8bc7bc151e196c0ab0bf3b4e4dc0e5dae9e507508711a9e3de52e2aeece6aff7fc8a1db65588de3272839390a35a847e29204d3b9b70e10352c88a10c86cd33e067fb530d20a3a5ffe67938c5a7a9218f1164f36a73324adef64da64d5fa5540d29a76a87ce010fb7d73a59b109280\nA = 75e31ab221c08b3bd73bed03f878bf7742f9b36a89bbfa7e90f9b05ec11edeb0140dcff6e9ad1d62cd7af34bb4284b3a52bf1b48a40f744b561d9ece056a9405ab15f508700b14914e4f427ea1df3093497410a0108066e9b259c1a26ea72082b3cf0e3a99ad054804da7bfa0200d93d65354b75e605b47a4e1e17ef851a37c59a95e1b5172801e6ecabf70f1e6e382740998fcfd8a297aaaba7d04b668e3d6eed40358247767323a8393ec359628\nB = 107aca18938a9cb244ad646a37a212859b3dda7518a5827aa2146b47bfb3bd08d772eb7a866e1f", - "674aab7a1c74cfdc2bc6e9ad1a365686213655b2c7b1977855bcd42ccecb804bc01d92bd7d2667069d853f18a0f0661f028955e39f71ee82b9ce6a81dfb2951b33b123e71264e819bba4d0a8c53a1d99964ad9ffb58b7cb5cfcd3e30b1baf5aa5b3cbd20a0df7ec37563e2b32b4cba91bbf3bb6fd1cbfb2fe0f84d720efdf36e9645c7e9ec70442ea5174528bb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 32d16f7ae2632b5cec2e90c34d191599acd9a1b5f97845595988c1d0d4ceb9acfafbc4aeee9924ce55e109ec88c57610fddc664316e0f9a5e3ed56ea447111c0383ecdf117ab42351b80e72720a4b1d98d4c73f5235507c5b4f7849d5e9b527d054858c0436ac3d2de2704c4bc25de4cc702f5880d5ae34094766938bee555c8\nA = 133a439cf006c753c132a8559ea13c64f598c5f8bd5043b89d04d7ecbf0ec58b225551c8df8dcb341198fb0b487774867e5b68f9058f58b3cc98168fbed0d0ffa86bf74b4fb0d4235976fa86d52b8dc7e82df176d70892954223cc484ae58b6a60459a9a0803ab856ff9699789172b163615e322e193bd758016f634c83cf50403e416ae241d9b1e44add17c2a663771ac88cf8b9dd94622d80d879ae41f0f4e7a1a32a1ab164f981900fc159aa85d82\nB = -fef33e21c07dc26a47d692c3094205bf4efae6af32f1c0f46ee579c1a22746a3663d66f2919f46f973fe558c61264157d531e66bb9ea10b4b49d9f6ad3ad8762a6ea8169a9cfe01d3dd65518c2e6e58e8c88d1b2f42d207399d7326752560cd45d0ff571309301683770793fe3765c1337d14021d39ea6980934c5fefadb93047ef07c807d0ea5625ae0cefd098988d6eb7af993c062ba313e23176e7abdebcc6e566304a5f9e03da05bc1cc58dfbbc898a67a5941\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 20877c7f53fca97f8e484ba31f23dcf51ac0f4fe4c5121eec576e043c6ec5492725f1b9f9ecfa64195f71909500a69fab2e591377cc2120bd5f60d3fb3812f9e80b2f6c787e0081c1439dbea76b819ab44bf6bffe87dffd771a870e4f5502609249c5260f91175fb217a9eece4166540be877d564049389306e0d6b313706297\nA = -534042b0811c9afca04d20d83898e7653f91a73de1e4b516f3228c6d6d9b963c7f8f4c36e05383da90f4edd072a7eda382c47b84b46b4dfa16f269c2d9ad0fc53ed2ce51cd31e4e32d0c1ee21604d3c7eed2deb35cf8df6fe1c0740a1515e4c702a2074ad6c0fcd403603b4a4e2195d19b265958ae854ccb0b41cf22480389a053f71544cf594f6833f3e4d91fd3d9091df0978d04d3922ed72a4fa3579c5fff50eee812dfb2a334148227a0f5739f8ac6\nB = 6935a3444434b0b03d27545721e253e4281884da027246e46ddefb01fa7cf7a9a030581dfe618431a68ef6d79b03b34f3ed598e7c8ac030e2b4cc887dd31664604fb8afe4e71fbc3135d6d3b4e596044d6b615de7184ebf8dae8fd58506286ae4d3b797aea911eb59ada39dac756d0e9eb6a6c767ab77b9348929a00f8e311f639d19ed88c86eb91f0d4cfddd34e98130eb520fcd2b77507c24b6804d3d65d1b21e6f6d55d1f6e92bba0544829687a096be79eaad7d88\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 24823628d4fe9540103ce5f611f8a6ccf18788120280179a40c2636f30a13e5076503e8a4b6b6ffca21da5b0f9f0d85feb2ce10b51292ed069f35289ebf5130972d720d20dfb8e6ee80c3ac598570d38e57ba33dbd75f1b03eab7847d865c3e8e471ccaf302461a6136dd13b8d31c9f163799a3c24c7284b8826608a9543816d\nA = -1d476cc98529efe5b926aba3160b261723b009e9b880bdea04e9b5b03f173040ffafd1627b38be8e00840e85d7acd3abbae2f7a60b305256b920c2b25a8a4373ebbf1a0c69f6e74792cb0d849872500519b6d1c190da30c572e26b44590b7ffdb464a900fc38db013feecf909b43bea549e05f1b7e70d6ad879c613293cf61f0cecdba1a6565eff1bfcdf740bf553ffd5bb7d74f7e9537897184c527b990dea20387bab0dec3e32727786bb14975b23ff09f8\nB = -2b6e12c87ad91a2fa878b9245875209cbfef400e637b557c868ccbd6e94dae65f1ef8caab61f292d739b139e384137a747210c09ee6f3b2ceb6dd212e14525852b8c54215191e116b7097f6729f6426a8bebdff86cdc16effa08d932ab512d7265cc0f57303aa5e6fd2afe0a45180557935c230558d02c3030b38ca88de5fc75c1240d25a22fe32c4e5096aad0078d50989812d7dd0cbb02c736fa563efd32d14109c44297cdb3d4fa3b93a2e15bbb6eb678e93e943979c2\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2c4bc23d0b4b1f79141be9149ee20cc9f1b58ee0a76d5f4205e0862492c18daa20171285d6ff0b600c358be487e78cb5450d151efcff8d53004eece94c5a37f49a15fb2b5f62a79568382cf0a4232407b139e1ec5a9595bee8435b4f138dd72fdc2946b03817e49864812b7b61f179bdd8389791178a95bb6311df0a5c60db2\nA = 5b0a181f07068af6e1e4b715d92c1b8391949a1e3cf0fe0aa49f3333c826f5582615d39ec28b1367804c1ef54f15fb83b3c578ef3ae957fc89ef22a343175df3ef2fd425f724ec1c3363aa000ef624d64c6d678a4cbd90b41cf7d69a7e03dd60c5d3470dbb75228b34d35469847772ff3d74b1a89a2c492c082d3ddb45ba4df6e3f228de6c64913b79679cbbbc36a2924e722c2c640d0c5a0e90ae86b5364dfbfae80df3d75823aa58ac6c1da78e988a11831bf\nB = 19567bbcf615b777b35fa7030db7da18126cd695ca7dda67f5146c97beeb20df24ba0fda4a4f03523a0d9b9f85d9acbdb5793ecf9c1f4ceac81299a1aa34417779175a4bddc0e95ac68309da51e4f115dad6fec33a75d0c5520692a38df64e8d684c9304f9e2e6ac6a66d2e16a03c19a30efcac712aed2b9ee774ea28af4f37c45609464289de3f9be379c733d711875216bc223f2f468a0c9b4a8277bfe49c590ebce2e027102537bddbf2856c3b6e9389c4d1f5390cb0f346\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 36e1e0b44e5afc35d1e19e88e75f030569eb99d326721ced9bd7416ea7367a98305354eeafd204f1f8a652a8442eb0823d2e6644e6320933ac481a3709777381dce8a7c165b23aebf31b2ea2745ce5b352acdf0707234c824da9e1af98bbedf80e940fba00c229539f310838bd625f1fc103f267265ac1243855622c5df72c17\nA = 1dba8bd9d1e6cdc117a5a01b5046353084946fdddf2696f831a942d9db4637a5ee76b84d4ba63156b8cbc72e40559a2fe9b8e2682d8ba1db0cea042bb86f8ed71f6609df52526c42e7494f6114bb62263d36784dd55d396018b8fa47fa49ca6e5c76ebb0b00e6c764e36cb3ec75e3af6a2c14dee01fab78070239638521743d04f184dae79d49a2bf209ddeb4cc72e0c94a93a47c107f5369070ad95ffce034c554fe2a8391e67f817c6cab5b88ae9748072da5c9c\nB = -849602ea3b79b33af2bd3ef9d1250c507d332e759d428902dbee054fdbcdcdc0a357a51d00aaafdacd696a15a64cbbdb7e1fdb347be5ddb1f609a4390a6f29f79ccdb51bd1f0547d0d9a2780517f8753a906428fd236f8ee1b433e57f2810d0ad51846304a5729f53a871d8b0e14355d24d3f092e50de4f044e2b8aa14cd8a51fbb2ff36b0b37defa7be768c56fbd4f5169d9d4698fb9072cbb0a037c219552728587d7c35f27456c02020f5f9374b6c53bcf8eeaa14be51899d3\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 77eb3cb5277ced02b72368e41f04a35796c2c6cc1273f109336fdfa745aba7c755b6ff3833e9b124d9c78584f6bfda1c94273522f020371107870c288592b7c23964320729d2308bac8813586e72078119852e1d7706d8e15c195486b8d94358736869b15d59c037ba4dc8032ceaa31eac3a9e3dc51ee17706a6956cff8537b8\nA = -6a0753edddef8b74f762bf802d7fe9b38638923ee2d81bfdda354d40df4422e6ac43724de1715c4088da2e68b63c10c90b236d7dcab39b9a0ecbce57628f4c2950c79cc88a89daa20d7a8679232c8ce5fa30525c56011570107697222e0eaee6871adced52ba01a3aea0ccc9901cb3a09eb4db2f93aba0083180bb41f3f9eaae00fb458381213dad01997e9b88f21b0a79ada1ec3837ac2b63611455fab6839363b796b105c3be6106ff284544bda2a32352bbce6ef8\nB = 542c5fde65111ec8a38d76d8c5735cee17329dc41cfd0f13bf47e6d0e0093a129f3449db380ee9a70ec1e44640839ff18b950c8fd89346cb4701ef753e6ef49dfd9bd27d9987e572bf8e68df399cf945813582fa1d33e07be938a7729efd9a5e7d730bf61c537770a0727f6bb9ea6add5aac9267bf910eac1b7d92ab4184734ef8b1d184c292b2b4295ec1bfd17b8a2a2e4d315a8b37b8ff9bf6a1e94a4772267195c5a7ea6f0a0c267337fb97a023f1b50ad697ea31451192cebcbb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 660a1f378a23fc3b47f693a347d90640fef43add97", - "29d74546933f4b78a26968cc9a70ad6fe8d85bf28164881bf7a99e8b96683c6f4fb54162c144f99a27e3feb736f0d382d7e5b934cfa835c723191e5692b7672cf6918c4a7a93b24af00b1beaf1b80320b14cf2d1539e3376779872542406a5df961f765e59f3480e1cd40b\nA = -1cd74c052e62ee8156ba5d97f28aada75211979b1c5925ed015ea75f693a04c4dd0a705f6a723ae7b79958884c96fc07f81fca064ce2affc70768923bfbca6049952eea3ae048425b7c6ad1611ed4b8b77f7605629b9d198a77a27f25eff2f82867845cc868edee4ae31afc5d022b2ffbf43c14fa01bef8d7cd9d0e58362a0ff9abbf250e43ea5065512cd707791ea4868e95d8fd2357b3b3aec1a06888ae940751ceab01cf9e49015d42371fac30d48ef5853b6894ca83\nB = -2ac904d3632e25a4d536097d80a157791a6aca6eb10246ea21f4cae07aafe907c6e4c726694e14ce12e376c02d326f4bfc02ed539a5b4615a3cf5c838ffa52124f9b843598a3821cf9f1fe94e7206d6a525fad1ef77e7e77162e8c6d3d860d4f568e8f81153dc47f167860cd52c1ca59b15f1eaac6b9023c8b375bb63b6adf6972af8ca62b39f044378b11c4a969f3939d9fed5cbe18c06749956c7acbf963f640a1e1ceab73fc4c77463ee8d1575d018f49bf0f08161ce4f88aaab5a70\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = cbbeda9c467ca801ec66fce801c6765a20148787dc6becb199a15c58fae8d20c1d391a1d9d57e1c74bb412e1b8f271dc2cc53c3355c83f3e2f00f15eaf0df735160a48e2273fd1bd75533cf94c5175ce67e79fa6c1422996fae36ba288a658a7a5422a59d39dd81ddea50979e933efc02\nA = 7ea551efeccda23622a1a5029e5525f46d5ccb83c28ec9adb7a3e97c2b7d936238c483a4a9bc92fe0e21208d5703611e2795b91fd5019272d255eeb\nB = 19bd92c534f56dc4235dfb7efff6d941112d66acf81b079382c86fb10dc5473bb8adebfa53ea3fe6e4df8412e7807aed029694ca786\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a9cd6a0a89578ea773fbfbf642e05935a995a38bbd54480ea3ecea1751370ef95ff5ad0e3203613f0ef6833237d549676a95b720848c5e9897cda82642a2f373951d5746b559bae2d98ac00fae26e5957c61ac1de95318b1b1aa6d5c64a6ceb6575f1b807060f9e2a241e378e6ebd72ade7d2df18d5353db7737caf52f888\nA = 13c68e450e9e091ae45863f6c1faed25906dcd90a43620b1a40e7a506e7a954256bab0225f3678e7ce6c4ba6e3a83c8f04a3491d9bf097adbd98fa6e78\nB = -ddef76382342178fa6636e62887fce6e19590065c766b047073329ea15fbba96f2cf088fa5a989f6ee3f6a513fbf66f621c6ea6ef2fe8\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a9cd6a0a89578ea772021f58ce74cbdd8c44a09b3937b198adbd8e95e8e35541eca26438351bfdcd8600b4f9b71616e1f16cee707c712d40da9a440681f8c8647bc90ba4c68b08ce4cbca458bebd5110222f06b2ca980a2e9419e71064324e8c36289eff9c67f6d5d011e6db8538a54aeff8c20800b0949fa42c38fbabfa1\nA = -6d7e88715e9854b435876fc9bb2d25218a1451efb73ad9cc5f52b2bee929530e6618a858000b3f24fa5f47b5f461c84eca971e38cda6e1f475f6612ec32f\nB = 49eb76e4614ac7b0ed3f534811a4ea6da5ea24be925ffeaa38bb228fa117ed56ae976b590d6c9d9a7a8546d8a6ebe4bba771d6587ac44f09\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 44f8596fc06afdb72a6e4f876b70b8d5d734589f41089c510b0da60ade642fd79cf8e705f09910912624fa1f646da596c137f124ec1a327beccba62a44f228f3c0977fda2af631e249b2a4de17d170df07bd812c233a96d17e1e93910267682d24c5c485f99aeeddceb658a7db258a2fdf73eb0266d26b92e\nA = -122231b14c249820f0dae625342415f0c6e7f93787b4206b79e9ecaeb09623636730810c7936e17a1eece68edc7c97218efb17c069bc59bdb9681a79c910c4a\nB = -3cdaed858523fd55553ef85d018c1097d7b88f6c30060d1e77b84821ca20b5625723c7d4331ccad1a70371eacc7f7aa11220f83f1bf3595650b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6de7efcfbc1e8d2cb14cbe4465c4ef71f0d1d7e80a1d80d9ac2d0b161d45fc9d915c54e33131591e8daeaa11ce02404c9b8494added1bd83e344ad4de7c04f626315caa56fcc5ca2ddd4e1ff064a2957afeb5d280477bf1f1195c7294d89049024fe821dceb53c7d270a8b4653e2fc0a4d8a3863a854bc3794753a\nA = 47423c4fec1eb6779fd23e3d4070d0a7bf9a946f5610eb469876797a39c58577242daef8c34926f6974089fc595508d9c573d0a275cbeaf37172f10b8c849a493\nB = 18ad789cf09e9ea182eaf43b28b4f2540e533f0fccad325430b73101c00e440bb64b70ce0f2680184aa8caea2f6f6517e9b80285fea8b61887a41e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a906994d3247bf8a00f20e4b349a500159d086aa863772e71a68f91af9d19e4c021843f8bb6eeed1df708d55047dc8faf219e00d559517632dbd1cbf4bda61651b9644481d052903be1970f04bb4ee8faab9adbbf858324e6cf5aa9384ceba655a1a107210a9497552ba8a56d5e0e70b0c757baa71d1613683707357827f0\nA = 122773509ee608cd9ab3ff6763629a18eae41be64bcfb05122e0b3e112db48c64d2a5a515d96a042850c1c848ae5fd5f0ccc57b273d25bd8d68568cb00bb17b1589c\nB = -af398208c01ec9700e332f3e694894c7cc412a73bde8a79e08764ded92f0d58db8056883972c79a0c9e0ce810786cdaa3629baeb9e5c370a5a59d3ba\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 64ef5e7063a1d95226569a27218e35e93d870a19a43fba9889a2ca98ca5c573fa56ebd77f1403b3bcad17c1351803a809c245a97bbe32b45e21768f28c5b11ad542f5e687a17f7811df6c8735e1778e94d9313c19fa32a6703af7ccbd88b489c96632d10eebb580cde3b905f6345a2a2b86a871b4fab36fa4b0dab9a6c1c5096\nA = -7dbdc37a51b601417efdda2516aba15827a40ffc304c523a47c544d5c0bba6c1367a20d8a6268a5c3f723b1b68de57eceabbb00d44185ec4ba7ecdce5d80456f8cfe7e\nB = 641cf85fcb5fbacd6214be4b7b06fda1b80f4683c21c1d08311f6e23a15434b42d30a51912898a1c46b46c00aef7ab7663ecba683897825a4b07d2b7dd7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 370f20360ac844bf4275f78b7fe71ba5db6f0bbabfbac3384c04b256eddaf04725d2d57b31afa48f047aade156c34441b4a41c0b2146790a2e15d13b584021ad55965588c6e55ed3b5cf5c36b780a27c5dfb72678d57528ab17ca2ac696aed3d9abb0ca448d9d5789fe37e632fa9709f3bb924c4ce34244d239a940dcddd9c77\nA = -1a0cc5b07271098a23f01b3c0d47cab8b294794b74a8b162ff3b313fcf85ea81fc99433cdf4450970311e1d5ff81e9ba27eb867073ed250aaa7795e44ba8d4000e879bf31\nB = -308f93984acb78c5dac2426d9bccc2e3ac361143807c7d34c24ef8f8db5e68a904ac8bfed1edf3cc90d21c87ae4d224b8c46fa42eea77797f94aa848160fef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4c8f466d1d9829aaca1a22fb6ca5bdba885606b9264933ac2b4c18e3afc0c406aa71ee7ff490fcaa804f457096e44576ff8096fb1d2b3c68450a8bc36d1a2797ab8b621ddc91d75e7d6ba01d86e959171fa428a5bb1f26766f94a553c94f6dcc2e0af90d7776ed3d9fb67e842e88f7d7342afd86e2f5d159db7304ae4d204a3f\nA = 57e894e37159cf3c161be9c97a946454e43bf09a7ae8e1437570a86c6b06f84005c1463d27d726afd2e25aebb1657eb78957a9a12c8749049d12007a81d766dbe008aad6d83\nB = 16dba5cf077403ff4af47438f5840f65fa4e058c5cab3cb730154ae0fcc982ea097c6d0e75bbd635e97314f33ec7e31f0e41cf285ecfafaf36382b33d5e83cd55\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee6", - "5c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 29d13ec304f26247a45ab6869720720fe019d6cf370b9e2df9a65828214aeb4f8b17969b8dd54339d08eb99bbc66720ed78ef79033fdce6da33501fa8588af86ec18be4c4ecfe01781f9d1379865100dbbc020b892e77027d1f04f8171ca51fb73129dd9a96568904eb44e19f56f842b223724a9ffe28826803185e4208f0ff0\nA = 135ebb133a0beb909101da896e3aad7e26ea72b23e60802e54cc6c58a07b1205e2ba1fef6eb86c420f011b70e3f725aaf9fd1873b6e1c1cc7005c7c09e55550414875cfe846357\nB = -e8cbf3feb7be7fd12b01d5bd024e47538f434b496613320ad71f48a8972f687992f97e4b69b5842d2d6a4176a5701327c40325e98b27e4c0f8fee5a457d92181e40\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4309b728306535bafa6787dd79e58324b3f86eb5409d772018cce2159f75832b87909a672b8b4b14342b352e76ec5a6dd66737cb0a20b81c5ce222133bfddfea878b132b6f9fd557133973a0b44aa41a01d54ab565d6b9c62da67378a4058255047a95923daf5f0f7adff2a3f06074ab1facd986d7d26cb475ee818199a390b6\nA = -7a63e108bc9790ab687e0fb8a1cbe1e9ff876e7b5eccfbc136ba05fed93412dbc2ffb1ec49518e9fb867429cea1d7f82e2b159b75bd40eb8370e8a54bf0e0ac0ff24aa3662774bae\nB = 51ee025b2ee8abf9dc5ebf1a4600131c00ae4b6bff966dae5c49ab5b9017e6b1abd6434736df6daabb2bde254022783764c94e66743dc752c9040563df7016a1581fe7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b9ddcb9ab858d2229cbfab87d87236e8206cf5e1a042eb5ddde201d56e2695a3d0b2a42bda6a284fbd2a5b2c2b80446ce88c024137780c277ec80bfa6e9d15397cc5bac98e58c9130756ed0fde58d475a033fd94b1fe0ecc6fd91a8b42177abf3f77e87c0847a4244b9fd4980f3b42c7c955836bc994f2babfdf9c5b43315ca\nA = -1f971ee9a7c966d1e82166503681afc280fab255665b850645321f67da8934baba1226e9efb59e0ac4483c8724f63556a213f2224b993e4e082eefff0056f7aa8a3cf5b655e0f72ddd6\nB = -39309313b04bda1103ca6f56514026538b4a29ae258a2a66424abe2c652b959f5c1dc4755ea37ebbfe404839505c2807ebe069c9abb9150205fe35bc286ca12b64ac46133\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 47555924c31f040619681d4a12064790e981db2c7853efa17e4d20f741f33c56d80862caf86bfe0730870b6c0afa9caf66e15047e60256fec29469d1760d5e9b77d79a84fcf7a1dcd0168a59f870f1635eb033e0ae0ac17bdb73da803206d48cfc1da48507cb812bea540daa2393321ccb0d88b57abdbf3a3bb765692a2c2ebe\nA = 754d78d5608fe8c7ed8e26a174fa27833a24c48d23f0e702454b7eb578cb107da537dda11027dd6b41daad329e036794de562d7623bed8d9b0e909cb3fa38d4d21a95c5f4246e0b030a32\nB = 1839baa8b8fb6575832136f1d4632f72f36cdbbdcbd00f197fff3cdb88b851cbd74910ef6d43cfae9d3248e9c85662d7fb596ae45a460feaf308823f06345bc5fae8823230af\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9b2f026b11d0674e9ec060fdb24b45fceade3070db4405b363d53df1219a02a664882819fe602f430636fc0bda935b14c55c8a0bbcc9b6683417e3ffe7f5d58fae229122ac6e42e76899254295dc5a08ed43c79120a5e5e4124b8fa6048ee90836bd2de51bbd2c6b9b53212e913cde871f11bf32f91b3a78575a006da36627f0\nA = 11402b3b1a45d67cde9730062e38aafe1d04fb1f8bb1975f25cd9098813efa2727cb229adf9490267bd437220d9ffa05bb993e45d2f889f140faed3ac3c7b53216455a830d6edceb02e8db92\nB = -d8e011f18bde068badedce8106f6602429fbcac4766334a0101b57fe94603203a4a8975fa499d8a68198aefd9e68f28e68914f920eea1083e37c67d59476bca9819a8bd628b89c\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3a74066e7eebd9b63a1dd28548be60573c95f29816f3b3ceef68a5f6bb797d7eb0b0f4ee612dca794ff82f5d7461d995b9dcc09649e2587639ea017865328bb5deef17b5283691724e8aa331d75c635d5e19ebfd268fe5471714aaca8b48aeb846f241c1675e18d35f029b132f81128f19028b0a471b3f75a530321135e35fbc\nA = -6c5dca3fb7b85573d1c8899868940794e428171e207b5f9f89fce4b7159236c0755e2959d870754e902e9c40dc1fddeeff6364f898ec0dd669283e6d26a612d9af3c3ab04468707bb8a7827756\nB = 5446269bbeb613e69286f1012ff62ea767965533624542f3b5c866cfb569d6193aa603061701992cb4873ea8b766606da1b57d7b37cf52f52bf85b58309387200b0ed36164f30d52e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2a4e727ac67451ca9dcba648050a085196460e4aa4836c5652de863c3e2a76213e0f590de3aee8639304c54a9dcd5f7d5d3592f647e3d07d322708e1e26329f4a31d66c7f2e9d482f22cd9823074dd57d14040a4f00ac2af9677a2c98d58ee1e094b1a8c40092e77eae454638bc3655e77441d4f218c637f95c147776f5bdac1\nA = -19fa688008a12cae228c6ac4982ecbc88da248d7ec785bf2289dc9103bfa3a91eb1e5fd6afe9e0cc035d3312e9ba64028fa6a229db6d0eaf8af43d8c410be7c689c3e557137ebd60d3fa04edb60cf\nB = -3e8c87fba4a41c3a84874c987acee9f560b9f027338b584a775c1fcabb766700f758c4d451077a9427257334a569037b0bd006375f71223add62eca19b1e26b86dde0cc251e48d3b60ef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 52e4a3f6892b425b935c6f9d1396d2034eb0331cbc5241e1d745a9619fa0cf0fc521585cb9d6b1034c5fbbbbecdc81c757f768c7a82f6ca291cf5afc98500c579f82ccf0be233066730f738c205c3c188f94b878c11268871ba42a5d950dc8a399887997cef2b6b68badec1ca641b88d1455e6d97a2841da49df7eeb766b7be6\nA = 67df01e34a26e8239c8edc7ddfccc3850f39864ed237d4dd67588efbeaaed1f884105508f69e20ff6a5cfae1516f6179ae6fb515a66ef0a7d633ba4218c30875287ecd0cfeb5bafafc492619942f97a\nB = 19f5076405b3c81519c0863d0c963d545b2834343e42bb3c779788cbb46d89be3f775b62f4114268a0ca0e6af6c0dd659607d40071dfe7f1ad0df9a5c53b741c04612158de396e9c96f7523\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8ac1d96abd2cbcaa8f7e3267b716f675aebd23694d24c112d202653979636d4d47e27cc36f850355cfc5ca16b78cd1848944f8759fbf6b03fbb7eb347536a9328a5cbb778a6bcd983081374a3f543b1380add14a9468358009ec2baa7ecdf13e7260968eea74083459406e8889936b2fb98c8b9a3597e5f9ca10b76e1dd0337f\nA = 1c9ab23ea37f324544280d176cc02762db7a39935f1ede9695b53a3ee2db49d0485c6a3742a3b5cfb51f3c21711bf89ed05afd0886bbf61cbd57b23439a8a165484ee8e4c0e1c0ca2b6478776aa2897d87\nB = -e30d28dd01655b7a419d939e3e7530258a667420fc759bad585802c63fe5efbb309cb502babdad0afb208aff5ce5830071c5a974604c69ee47f76fd87e2460a5b03a57ef0185881502625886f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5df0700adbd880a5730d8c0637a362a9d42c64503c3b9784046b946c2459a619b5bf804a41c92ed6370bba730c7d39fb2e01558f7ec38511b0449d6e9db8df2cece4ed348782ff1582396ca8b3196474e7e5817f8c197c44d771923b6e286e41e7e23c33fcd8765e06793169999544a310f2e080ffe13640b85f21a18fa11928\nA = -5c01fc52e86f3a344180bac284d2376d1bd693f20a46479c77fa57077df62f83b1e81c94e577d1d6733d276f9cf70555b20e3afcb97534e4e0108a6cce87e9292d78b2d7367ff15fb33d2c3289d2a2913b58\nB = 6bbc39283be06382ea91ad6b1630b38f32385ec90019d2ded7ca6fdaa39defbe22585be0df9c0cf613f6f146c71f901adf525336f6573f7f43e661c44b7097f110d4551e8c75449da8fd39201ca0\nM = b18a9cd6a0a89578ea773fbfc0767c8ab81", - "7cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2a01005f1f387c4d8d24a365708e2506b044f86dfc011262d3577f7313a8f51ab943037361bed1858e021f8a46491a5c73284c666eb65cea1392a780219f13d7188721d7d4b975272293a5eef63480f30cc9618aa74bc51f4175246301a46fdbd34a6ec72d5974aa920be5f321a97b8f19c0ec56ba10eaf2e61f2b45f134b304\nA = -108bbd8824e8c16b81dfdd4dfee691e012e578cb9cc80cf050c0ec4cebf71a968732da36552979ffaccce6667e46c29144dab75132cb087681d5549dc5508f3719e129553fdc97f545d7ddb7d3a4fc575ea67c5\nB = -2ad4d4078c47a3c8f5f9b48e10d52d72349ecf0f54abc60bad63bbbf4d8efb185de90e5e1a686859e1c429e30977fca492aedbf084019e9ceb4490aa471776ed2e8a09151b37c5caed9ede66922b7ec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a1b1b2d33cb610f1b398e03f274ef39a583d13af14b79e6766859b9ca748237b481a3cfd5d490a073e82e3c53d3ff5cb6219b2b2f71927f27ab6f567547a22dd35fb5919e1ed2b6dfae4d536d6d44fa6216d94d26b33f52db06c4ecb29702588b73ebce87569639f786df4fcf569bb07d5379bf8b83743327248c2d71b5dec6a\nA = 5bc53b3895cff2bf7bf10e24fbdc43d17d277a982d5d92f17b9b5a2b9ed8b6104229292ef3997591e2e6a116fca21ad5d061ce438f33b7f7110293770f8313077152c7546cd522ef4054147edbe1878072b1043e6\nB = 1599b541c9809779df3ef40971e7a83f21564bd5d6596d51a3d96defa4dff41e83ca6247969a3dd9a746ab72ce21137f2d7ea015ac6b2ffa8a32997e8b821064d35afde3435b23e47cccafa74d5192535b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4fe8897417446c493725521c0ea5b2110f91a1b5ba236cbb6ff3f52b0036a49fc82274ca949ac2b592fa4bcc792114bf2f2a78a2cb44cb22c6fe7e4bee7981604de47f6da2ed1fc6a8eb32cd9b8aaca0f2feec76a2438126ae6f409645d897769a6d340308f82dbc6a98ac059fca6f903c5aecd668fa838b67300c654d4013e3\nA = 1717c6503d069103f10bb4b36427fbdd2371b30793e492e4161fe185b2e27469fef6a25566d6b46f6a7f97446315a22d1f1f662f912b17e71feb2c82411ed7eebb84d4f594deffee14934b75a845d83761f36141ecb7\nB = -8808f540521c20eefaa037fc5da782c891fdfc668b955eaa2e4edb592e027a964b4cfbc94c548d785d92992abe282d90dd137c4d76419926740ce138d567da7350d89f2e56772d8f5bcc9ca8d7076540fab3\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8b9311808bef497d8a5d14f7d851567a196a051610246964917a1f9d4f4449357d2411ba9fd93983f6edd76b8a8e1501146b08b6e1fcdd97b6a41cf637b6ff0cff7a2d6351aa1ded93f8fc1cedc81879eef751bebfbd1559d5d0320595c79e3eb1db0951d7c67c663bc57a672faed9e14c7da6be6b0c6bcab3d4d515e51a0b5d\nA = -511312fce1849c3d177d42088e55d534f9f7096282916e16b041f66ea90e2cccddab5cec0ba8ebf0b047ccce72da349f420cc28ab19bc156c1cccdcf5216f19ea922698127f090e97444751dd58fe7a2c90197a9ab3d35\nB = 6a5cab5e322d5f651f798aebf43a62af772fa2cc379905e72d253c49be8193a07ae6164f21cf08baff906ef800e361e1cdf1604f454483e10c8b2bfdcce77c12b0320dea63f9ac0afbb86115b656d0198aa883f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 665e16ba6cba87c646637a233ae04805a302ef4a10d79c5b65b146cbab8c9ccd491faa32937d0ee955dff7dd0ea3f79fa43c133021c8680490b91d9c1d8a8102ab709ada7508bd59042940b2bd3a4f8c195f781313e45fa8d3abda1f8e13b35811b638b2ab101d1caaa92188d2b75b2b10d596ab159583135b0d4d15fcd3d882\nA = -1375af024e9974cf8170801f4a709b4e5862ab7d18464077727bfc2581e557cada991e9484a1acf80182458158c44871e67e783f7573f214ee4ea1f1821a65068f2bbbed7575f03a4bba36b0fa8cb6dc58c73b100a6c4a6ce\nB = -2d64b6bd987d496a3c121e89f4b0c88b6ebc6e30fa9d47981b52862551f3b7251a3fc376db0f2d6daab6e6fc5ea8fa10b040d0dce334ee91d8cfa6db9648df907b199bb11b2b5c41c67d72b760c404b0451f70fccf\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 49e9709810d9f3fef159e5cb45211453e7a94878dfdece19af839b89c0e43b226d7cfd46859963c7ccc753350e74c2501131474e3b8e0edcda18583b0392ee15f1dedcb7144000fc7fa7eabcbc83d12983d2ade477b4687d75b723c1a98a951d21b2e8ed95735aaec77e00de288d16422fd259c665a08a34331cb99299ac11e2\nA = 4e550ba2fc2a44452f068860ce2a59230738a7a15f5de0aeb4d15bda8c61ee3003568dc5971e48343d402112d7a86860a7f08f5cdc0de21fb1aa064ee5df26fa23839b5ff6adaf64a4a18c07efb3582c2fc9612d2208fe99f8a\nB = 16f31365545772f276d8ac952506bf4033a884edf1ce583a63d8d9f6809e29d9cce3b3d227f839e6c09b459951465ab4570d2d36127c0f677fc0a63975801896f2fd17887ca16ff7f265e2e7adab1516ce56ee1ee9de1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 89ca20a3fa109a65b9449edcc729fe97ed45a9bd69eeb31d4a566ec1787b24cb7a2c25b3f89b36fef1cb3645b17c69ac8ae243cdba35e17f5738b35278478bcc391add0b5ec42db9ec1eeffa63a3ecd2ac0338db57cde9d2eb9ca4bb1df84f1a62245c4e585c4f20f26c98fa1957df34409a99a18bb442ac14f0bd309266a35a\nA = 1fd8a096be30e4435ce8cc604ded337a3d9d2fbc9666d1893c38546c4e155315b536d1bc323c1e7be162bb0fcd58440915b053ca0d0896e99265241f2afd46605a2a7486e1394a07b23f3382cd190e943e596c747b6529b04bdb13\nB = -a3960a51af5ecaaa70146ce55d639005e9b6b9b58592441d5876fa71470ade6d1e2cdde17bb80532551bee0dbbb71a0cb24dc8a129c1f6e28920055d87e9c66be27fc4b425737f36add7d72e39bc83aabee5534637e2e22\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 654d9c55d4a62976670a5ecac3a6165734a65f1edcc1ca81a8c444dbc98c3409ac8c4f6fbb92f122045fef8b7971a276c7dc4eaba21f7be7495394053d4f9bb14b63fc02c8a55ad8fa9bb9aa26aca5c47968ea1b7646ec606f53606d5529ded83639984683b8a020e8ded4b2d9f668ceadeaa8160245b36a819db14e58cf2bf1\nA = -67abdbc70db183b8c25b0664805ada269922556bf15aa80a47d31f215e216673b8d59edfa10a74f3f09d066055c3b9abd5434ce95eba91dd51576adcfbc7e2556df95fd6642a3b7e0486a635ed5699eb7fb285589c887c8659a2b7db\nB = 6ad3e854ea57aafb8980f1e99ab9cda24f183dbbc513e1fc92d4e239077816843f47927bac28e41d3f31c9ef134b72c09dcf14e2e9677a430d43002ae70c577d9958341243030fe58a800a068d6b01fd377e61844f0d434dfd\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 74bb23f7b0cde7924ee52e58bc0680f151e6898cc1bd4a2eaaa05faf218b419a19ebf85b0219f924a26002f9251b83506684af659e5b680e05138432ba227977f38a479ad9d1f3cf68a86ea214645fc4bd1a032f995307e9c9ee432e816fd852655ef20214e24522c17799ef41d1eebc6e097b9792757f7fc43124c609ef9696\nA = -19d3e6fd6de9092cbea55d65154208a0c93ae409c3ee35569cf774b8c8b7b1c9dfdd52e9f408e14ea3153073ed8d92746474e524a903a45a882fe46af92b033f2c41eacdd7e3c1ff661dcc5349ed6bd1aa845eb1762f27593708aa185c7\nB = -3d466d29e8c0008ee6f402551e3d62fe044787bc9f243db9252ea97da9bb75f5be416def97f13cbb008fee77f2eeda672bccce1f36fbcd26e1f1299619535da0a3fa3ffa0c6fee82a494efd7407cc770cf46ed1b8b143f42790a2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d4", - "8\n\nModMul = 197eaeb8221b431d5fed3d701a175abc146a9fedf8060e8e611a54f8da2fb27d2fee4539ddce1f3481e6a64435f09a2d5012540d6069900a332461471b22192fb87b63221c7822d3f2fcc35cc38feb6b3e49b5b0fceb52b0ccbdb4e1fd7b0f3eef3d582a6ae194c249ebc52f215b568712b3e50bb8e01c64b114955ebac2da48\nA = 7bd216d0acd4ee392258a7341cd56bfb0968492fe75da0c9d935713a6ac883525a4a520b5b7940b05e3f5e0c40372cb11b7ca193e93f0d3883fe5840e66346aff0f38829322bbc1f0a0e63ce5e528ba5b13596ad7ca19d20b2a7c9bea4214\nB = 1ed4805e53630b886cd733e5281f6d2699b3c79da615f4056120165cc63858ed2ddfcfd0af0c5fc54662aad90f26c55dcf70a30d04ce05bdf61028730b900587716e690dc0c6e02419622ab8c115078b92315e7c7a5ffe38c4a404a2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 40f69f2d1660eeb6e1840164817621dc95eb930875333bc3f62a644ca5910c1080505de0d54fc9fb6404a61bb2c03b3981e558abf9e86f2047c3928599b529ef3d91c7ccd13c1d69431fb9ea3f02b001427cf519d9fd8182219ad904f47b3785fa05ed24cb0ceafd537311633a2e26c27e61be92eefb28a49d7f583cb6e072c2\nA = 155fb75044fc54a6ba6c46972e2f97531861b8d6afbc358db456bac33a44bb0545deea2fc83023c08b7be473eb68accf5b65b3c5d6af88bc6d8ce722c80d5d1527e475905226b01ab9d7b5a6557250cf8be935339db330df2dff92f2e88e80da\nB = -8c6016966a2cdea4b2d8625aa367e1d079638870f1b61e6b3c3a1e6281ece41018d2ce93684d1f0088d021107fb595390664c11435c6c0a7b93c2c6895217a89c469a37d3250dfa457b928ba6119b5c9ca5f2d47b36e60e4325bcb4383\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9b9e6e1727326fea099eeb008a36539f3d47e3882b77d6089032b99c6cd36ad79fa75b7c19d1509b3ff022ef781b6a8c16fa6881f9ee2c4e00a4dbc93a49829622f4ce6ba9c55639656102d81167ab8a5e1fcf14d71caa60be732f1fbc71250256520c7c5a4579c3fdafc39356a2bbf2c7ecc526dacc0293c7578424c939ab6e\nA = -54cc11ea9806ef27911ba721f19e2ccb111045711d301863792f0cfac798758f0a29111e3a0f84d294a79721067f50858767abf507cc10ec9ea3eb27a91f06e7f6b7b4be7001b548cb7fb734166bad6739935081bdf6d35d58ef56180d377e5fda\nB = 7263e8b9a6f5387f44c55af64b64160efe97ec8a8159e723ca8977bc17c861e22041ea227c9c9bb467faaacfe352b03cc620eceecabb6db2db108b49c69752bd0cc61a5e998ac2f404ad052a51286ccbcfaa214ea8ec14cd9a2a6db56c3d9\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a18a7498ac9194f600cea3d66615595c27a3efa7ea196ba12a80b5f608f85fa72afc366d23f5ca98452dd190b8f86031a9dc097f94a217b29fa676a6042a3aed2355cc8e767d464a8adb888491c8cb82dbec8f117f57c4a07b41e7e6f6cbd7dc25418603b1d1d865dd2140a649c9d52019ef39dbb6809d1b28b3c1ae64fc6813\nA = -1b663403c73e4a9003467ed12766f16354f79073ce89b66066857d19f3b42791eb360004d23e02874254bc6db54662717739eced153944c4776f334576746c5c4145b21a23caa2b2a137498554c7b749efcaf3393c5457b2bb87ee2ca3bef5f191107\nB = -21d12aad97a5c6e639a2ea0a82b1292aebd418567718014465a22b9ac5c8c927963a2a4530c41d5a7a6c14805e56a7092c8716e4767b54a393d8552c5d3c366b39fb3b8667c60e6075e9293bc938e407c53afdd1174843b76aed187f56bb4be5\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1983576ed73d4d87d8b94cd3f70c149c0273e966176b85fbbbb7b3202e2c843bf1f8f4546ad7a4916ea4c731a22bd337b6177fcd2da8bd301f3af9bdcad800449b57986e7cbcbc7eb313d6512b2894c0cbb6cd753a870860a49d6a682c20b5e883b8c4839b3321aede51bfc42bca163a924191feaf05e196d8dcb7fdd9941a60\nA = 576759af0f02406e8dafa330babe9473d9d970bf371ceab30d2f98f4470f669e042e1708e2677d52cb9f99deb9b53f30727d16c389bb63e71e923475314b615762c7612269b5ad7bcb5108068bb5159cb8dbb8d08de2bd4fa4d9db6cf6e3f5997b9b416\nB = 1a4e34794747cf4aa626e964b839ac497b1357090ff63088f9fd4399312df894e41b395d17b8ca1806baec6115b1476912ca9c4309f00a46d5f7a52c8f640075422af06d6d6d796359132f4955072ce90e61b40c992a155b2bc31c262e753aa7d00\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3448648ff9f7425937b6faa54551ce14dd15566e5d41b2bdb1a8db62037459235a5b9546d289cc2295b0ed584fab2e1a798bc25a0c114238f61ad3381a5b441cb67f92cbf66007c980db3351adb9cfd2cfc769b5b9b0bd1701425ce1ee8d4b9f438ce1207fa850aaa1d3d1f970aef874c2b2499a150d29c2ceb7bac375009b77\nA = 1fb54cec882c274b98913e76342a9b8e631bf1d381fd8a4f7e0eaef475642ab3f5da70ca2e38741bd0182a959e5e985f1e0e7d737beb8c725c9b5ea22f7ec25b6e564809601e8405a5b1362e7792791f55ab64a57c03a99a8518d7f65feb0e21be619a6a95\nB = -8180d172d3afe00e0423245f47591d5f750f20d2cedd8ba6ab6f9aa24f74498a96c9001a0124c4f98dbd402b63e71eaa3a7af8b0d2fa417fb1d45f64e10030232b9155169153496aa202745a432e547002954eedda7cc9c1ca76811bd902b192f1a1d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ae0fd585408a99643271eef575285a6261a4c4a92c1956b1ab436d3cacc8d4cffc07044e57b357ffa43bfa9aaea57824319579c5c3e2fe4dd48bc818178beb5fc1ed60afa08828657d00bb88894c975378b1dfb452a5b88fc3c1d81099644a998a47a497c8a2b12c444fd2a088f47576b7f4fa40f34a208fbc3348ce33e59150\nA = -7dc7dfb753c0bc3ab4d07d5aa78664a7f57d64be4d4780ea81e3efc967fbf1bd1390248bbe259da32108ad96bd8b39f2c9f118bfdc96bd06147f812af831288bb687e4e1742dcd1dbf2b7adc41afa28d07dfb8df8bb2da5359e66330f5c65964096a96b31dd8\nB = 756f3e407a3ae698f103fa37759e90554f38378a9b8eb38581e0970ec8f9c00f8392612c61aca5fd37d1063b78c19e3109f35c0684ce523c634190b3164ef06959cc42e2b77e1bb2fd50eb59c3dccdb6090beb809ecb0ca30457a5c5948328eb218e219d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a2aa4550e855623a8ed488bb63db8fa4ac374c1ae953781aac590f78a364fc33380ca2806445fca5bb9ca2fc7ec4db5819dcd5769e3b746286c49a7c80149e7fe276d095929e2cac6ae57e8102f7d4c96261ca44cb6f1601f429528495b6c3169e15f9babc5be696074d45559d5abdac42393094c450d6a4a45bbf60ed7847da\nA = -16d0aea9c752b2e6e4e13f7ab1f0a2c1776874967b0dfeeef7e00f8d9edd1e11d2aa702be45fffc284c47811c51dcee184a134b8f6d1874026eb51e2ec80c94837af4602cac3efde556ebfff578fcc56c00de99a43638ab68387ec087ee269ca64233eb5b1762ae\nB = -3c6b60b0ce4b13a5d6d9ccd67c76ec6b71b94ea7205e408eea099c7ced2f3a462954741d353d0af850b10ffede8ce0bf80b6893288413674504829793d7ae0cba53b163e3f26cd99beb0a9ad540f6d2cd5097beac604b1694a9a2f4c48b28338f9d6a63e75b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a1a8fcb68c53846b3edae33ec070ef5cdcc1346ab3a98a116344e6d2810e2e3f60f0fe435fe7ff257c7ef4c122b3c34c776f4912a9621b6949308e2cfe2e0827536c7464371ce804bd7cac1d76c5bf8b4a6fd4ed56b65434c3fcf0ac7be543fe2d09ac01c564d7b9b463740dcdfa9068d4d8e33f29297ab452e6ec55c263de\nA = 7c4878334ccd9e20cb11a643b206626ea5d0b20973f18535cd8f0fc2f0325a67d3558e4cc9cceed0d88c6d2215c220b8d0ce230fd701502b02081e3f6548e58e02bc2e79e4991f8ef188a84b0a367758b4e534b72cd87de7f82a26de14fafd162a50b359574812cda\nB = 117d8b1d2a3e2049e6edbb9494c68a97145ac3e658aeaa05e8ecec4b090d5f467cde34e05fa7f5fbfa32f1d9dad70955f22130c358468eb371555fdf57a40e1df398c166a22a9df2e1f4e18590b00856b4f880f6629f1a4296056dc66a29b6f0f25490c6a8209b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600", - "540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2cd3de06953acb87b773b8bb28172b24adb283d6adada676f5f4548990827635c51506c85670767828dc5b4b91b45a7ab89a700d70bdba4e0355da32b52c173305767721d18dd2cb6c55f890611e7abc854277a453c7500efc4cd4fb8e6c9bb7a73fe5c77045e715fd35d415b3496f7463ec902cbdc18f9f6f67c33fd78c3210\nA = 1a20ad042f46330df937b879c72ef00dcf39fb85b59186b8e7a9d40723288677ff6ab2b9bce95f34f2de37887c8a9cdcaf231254bd00c7e25b6042695d7dfc05a11765120d1dbce29dc74f35aa1492ba0c5ee65114d9a246b57dcc2eb2ea4a310be98383fb934121db20\nB = -f8ec67323cff9d53499ceb3afd44b28f0538c39dae8c965ea27d645b430c2f8a4965eadc8ed864f2549eb636ec558419be71f986f4c5783d0dd5253738b876d9034735bd13b18fc670438387f84848308d9357ec2aa4f6a453bdd36ff08d54a6800bb41df416b17d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1aebe2bc35eb2e449bda63513b1bfb55988cc8e6ec8b3c8fed5ce4dcf53b95f1b438c41e3b2348412b35e1f734edba30273935b03d16efaede429960442a01849c352349e23b4af88de4d01e9ddb53ae900418d49a84b7fadd2669261a574557c4fbd782f8e8f400895f6a6c9679b72983ce01bcfdb641f5067c94694e9eb80\nA = -5f97994c39265b5389526e3847876a10aa3699e3c3762a127d1a9f892180cce68ca6139a6f71b235da26c287bd3e1aaa1436746d983c23c3105c33ed2e06baa1e880f1744d81a80b98ee1f16220940d721a92118a9b949d4da7d1477db8f5b357b3ceb7df34eb5f62078cf\nB = 4bb4f8f4f4c8e63238e8774ed61a7eeafb3fe9a6e19cffa648defe82f4846e3378c892d223957564fcce79596151658a726031a6921cdca0adf0f5325d858c048a6b94312ebfd19b803eefcb93bbfaaddef120ec3b8c366b6d978524d5c74218da77e4c3b5ebbc66cf8\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5d64678a32c163874d1c81824d628a1051bce3b55c37055acc47a8630d3fee648df5d319e50b4c56f465bbf696433409b89c07e442425d3018a059ec757d77b3a40d516ca3148010036b003721ec9c999665915a3c442d95ec3c01c232feb201be08c88fa3c6b0769e3da30f1d73b66f98e31f4306bf4e23de78e74743b224ab\nA = -178d81e419f0473c426e24428caf25d61b648bbf963f7fb753ae15e5ea3706b53b00bfc8fe917ac9fd6c7096518584566ff71e6d35197f9aa25107a235678cf9ff8ae1501c1d5a15d2a27d39d066e169745e1e8c808209bcede0d732423d0c9cfbea322ba3201ebefc5315c0d\nB = -27ed464895b65d9518923fde5caaac0c72aad0d1b38fcb7827d6ad4e0c8dc09e119b8b98183f0ef8d5d1133f3f108e951caee035bed0d48bbeee6d1ddbff5864bc192b84eb8a500cefd223972ed51c7f720d1736646825f95f2f10ce6ad47a267bdd8c80f65d644df158d7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 52dfb6bcbbc5cff46942d76ba45301cbff76e9b894703a6a7fd1af29d615336372d147c3932589affe5c6533f28d3e6a57ce2d3cd7448bbd81e09a13266ea31630cf044f654b87ec3fa3294eb65873964110fd42d86e78d128bead5f117cac98145051552cc3a86c193d738b973f866d068a8994a49df3fc7c7314fbd9805e80\nA = 797c67ebdc083f3c8b3ddf9847b7f3c2a39e35ce2119f746ec87fd5d86671d8fcf2b4f6d440c43e93f45019032e629879799eb58adea729d43d2e40ede6485143bd35979609a12faae7e4393879c40c0511c886c66a24454e4f9912bea944eaa417c9942f09ddfb227feb14e4b4\nB = 1a599d1cd0ab3614f50b71b93c999942bd3d4cbfe7900122d5083151c71d9e0c299bd927095c5c3291418424a7c12947389bd4e0a3c2fdf67b3f512094ec0ce5b52695e527de2b3804dca2edaeb1ea4b487911053272ea926cf2fb3386dc4b1dc268b808bbcf4eaedd21168ca\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 99bb9082e4537426c61f3b813f8c97675c44ba9ca418960ca6e2464cf61ad4eabb01ba00798463567ed3d829d3f14201c740f19fca623b1e9b57b534a65df0f070a2130489afae89b91003cee432fab11426c4d13b7721e6f9db1bbaf0adc0064b33e4b9f4b795511a0744b52f93e3db7bc9c0a991e4e122c463ff344fe14cba\nA = 187a8144a0045a92dcad94f0bae7285309ec8fac7dc864b08914e5a4dc3b1a6bb9212161a18c22682ace16a4bf3c03dbaef088b09844902a3255fd6adc0b7c6397dda86d6ab67204d8061c36ca20fd4bb348202037b249f6c110c31580148db46dc5b1bfffa38a683a27054c35326b\nB = -e93ff16817b725016279a32dac247961ae9bb00af890fb49c4fd8cf5e815cf98b58cfa1e3735095e6034c9a2f2b5d8030ab30e2271abb45b347d755cd9ab5ab5ce37950380cb306bbec42b6b8056793a0955bcaeb23e2d6a9548684030566eca2d34c458f224c8e337cb8e3c252\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 631f53d02c031f592b3dfaeed106160488c08e0672083ff195b22a2c0b006f11165a245acad6f35dfb15a871a9a2b45c544111f71f86c920b42fdb6551e56c55199e6173c00e27c9f47256349a80236bcfd3acd1730f823031ff9ef594725cb9429ea183a7fb2e03124ebdd98d435313e43819d995c4fe81fdd4ba718aeade94\nA = -72e20f1aa2b5f2c4218fb9e11ced3f45a218f4c83a2017d97d0cfbbf227c9082cd43f939c8909e52c8795cfaa75d80392d3649dd85ddc35bf1cc54ba389bed9e9dcf867da1c05eda080274beb6b868b54fc85e12ae127dcbfffeb043f9d59333d0ab3374c24971e1bc7269450b418c8b\nB = 61cb021a3a957703d14061c21d3b0fc19598e19a17df9d6f2418c76d4d37b3f62bd4037aeeb1eda37f83df44c440f5e49924cc72ec5b153856c6b621350ec89d98859d9d1ec7ac4f0c418c6599674322e7d618c5ca588d5a873d5af356d4771c6cd375f5dbbbc69f50b982b8c4d1ec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4654a62d9491f28599a976288cd2068d8e3228da12f645413a92f482efc66d1737495cd4a4c733f147eb5414a2ef6266a116ce264491a3463c9df1b030d83b315f76f3bef8cbccb5c538478a65092547b91e991e6be91ce4549c3a6e34aa7b466e63eb3b88054f6714083695c616a078ed54e1ae46e00f3593af845fcd0ff51a\nA = -1a342c154aad619e567fd32e7053aef8d98335a4fa0e35bf06acd7998c43d821de1076dc1fb67dfa1156d7ff30203ec736384a9aa7f5f08cfb302eb3a2a7179b2664094c2cc0df73fa05bf2af24a62b8e394fc76014dd83b434df26f8a67a624884a0b9b4f08f33e9828ae64f5d0c8cdc2b\nB = -2c57e15889c3dc9c94361c17585d506933a72fa954ce44dda9f5e33408552ebf49cae87bd0be35197f887fc6c7deca1452a4345eb67d19bd2e7d3dcf651667a8900388e4d5ec71e9433e3b01d2b3d91bb94d0fc3c51c70793f978e4b5ef93a9c6356c0b2f7accb9e4eb457a2174b50dc6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6124d9ce4de2880ae3811836235d6d89a1a4b710f1d5a517153ed7729dfb5b56b0ac10a4bbc811db9b26465f03cda355701f9f28c5257fe288743cc0789cc54a8661f46e36eec357580b00a84f1d4c8e3d689bbc18242f1cac30a87cb7a47ea06f80d7c5633cde4c8cd8a1a7e27acdc3a2aacd608cce9e2efe7864d41a56ceb8\nA = 7b48a9663d914e0225d7275e965d866ee6649d7267474d5336d28d54027ffe8572f4aa26230dc7abe9957d211e6c2c8f3185cae962b878cfdfaaf6cfe32058c299247f372ae170a1f7cf71380787f6e90995da9ca5a4be8ab1ddfa8e6e5dc65b6f168b9b8e29e0257e0eec853a6e1911b1afa\nB = 1fc4dc77f4a18d4406a4ba536e500aff68d133c6e7725717ae6537b527c6f40f93202a2292522fe7d04e0ef804d1a7013b04cd3d88462fba31534770b56d2e5672e8a6ec7a723186024c40b4717defd1433b9967bd692ef81d5d4e39ba10a3223d250ab6e71d5d253dd0a732ed386ad57e54\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6443de73e1c826c90aa36fd7ec5d0c3324c42058b1c35d3adeda1685470d363732d23cceb08c3f973034c24fe65506bd33dc45d7d617a53048dcc103d3d1b4fd0534586c2fb7489ff5ffb98303bb068", - "fc14b1bb6bb43f763dca2c891095e613bb7b6920163aa6cbce8cd93d9d39f4512b6e0b28d361ae11cf76037eab4cbc819\nA = 13f739846ed2c3aa0a1923168cbb46f4f0a2f3942ba57bfa5c426cb4d4b3d80d9530405a31bda329a1814c560d54defa3e03fc4f808606a598607783d539dbb1338d5bc0c2e272a7ff6ee6f93e1665d6f5a0ade30308fa047db086646c763106cb875e014e2c18ff8837e4d4d86861b85a5b7197\nB = -ba019333046f76325fa9f258006a7c10d27e89f6d482b95c79296c07a65b8e3bff4a9c9fa7e5d0038da129390ac851f8c0651dcf655a3d4164a731cd20a701895c12a906c732906038a8e459aaeb293fda21346964a6d53fa3e370ebf43c7ec8f66229405095c6a509d0fa15dcf45de8d0e901\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = d3a6fdf4a26993edd175de9a0f012e1eb15a5a1c4dd2741dfc6d0f9177cd5645508b8ab09c7fb34066ba893c38144c7f2ecadfc2b0d15728b407e5db4fcbbaf1871580426400433f14dceac43d28f03376e791b7ad01a112981f29ff4b66102305f0ecc4fd134c2cdc79a5e9d9f085bfcb7e6c187980e68b6c7639c12e8d200\nA = -464cb16fdd395e32fdc613c63ab4768f8cf72a5b74a0a5b0cc581ee4aad1972cd97db7966d3124e30c9a1c80d85c46da2d36eecd7c3bba5866f9eab4d0fa55b2d440a311654466432c681372a80a7896c9163c12314ac51f652aad68fd9012dc63fae6c7673c5da8faafcfa1b4ed5550f2baede5cc\nB = 40389ba4d2f5fc152308c9e8a8c36258c770fb2d03e6189b96c4f8dee97ccbe426cc14595c8482e9e22486b61fc570f0e7aeddad2f4e3a480d4b75d14294a3b912928da5692043bd98ab88ece87a9bbd973ec82f990c0ae6091245318c2810187d69c38fa80e835300ed06c0723fe475f3fb22de6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a0f9eff3a210912828fd7b5f2d72479cc9ccdcfd3e8d21739e301de02dd5c257c7ce4bee2def06c9d0c90d5a86bc45fa9f31e456d353775916b3d5684759e4500f99ca1f91f6767a5e2f4b735ae4b756d56c358a06447fa2c2ccf0ce667be4ed143e9e1dc627a561d92ae53a62477270a7944482cbf671138bd2a85fce92b08\nA = -1da555639228fc6ead68049d836d60a4927ee77472fa0ffd3c787d55b6067012560f5b1c2ef8bbf6119345dc6419444c675c1c9cd50602a93ba3718a5b3e1a30bc108d796998b24474cdad19bc2960b295fee97e03f2ca7589a3daf35bd28eb37a67b5d2cb35a30998d5f8622bd7e6b7d3fddd1ae9670\nB = -291fea1ae6dd1c66c62ae3a3d22904f4b4adb2a48cb795d50074095345d661a033f67b20c5d7231236dab871892deaa9458c235c342bc81457cca3f014a75f5124ff4da005dcc1108e75527528e5cc9c051a97fc6cd202bb9166f9e72e366bdd77c965a70592e5684fcaaf2e03421a2025ca190fe158\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 50f4d25875150bab63e4162265a632109d6b4743f9d6b55306858034732a4895ffb3720286acceff287c38320ee9945dcd0a1bbe5ae1456b7f36337cb7d22b679a6821a450765471257d52b6ab7d59a763e75e9e64581a93aa54761f6a760866d6baf186cdf4ad2b1a6af26a3e76cdc261d1f07b0a7122c8ffdef595812e7208\nA = 78a1609a7f08c93c9bf9090ca7c93459aef815719b5dde5f217567a9f68ceca05594f6ab17a4666ce1c0c4434e0f4f38ca1f33e501d6958a10da47211cc011da219d4373d2bec4b7c6477b1ab3b00b6c45279212db39bcc11d1e7ba49916c4271adca7eea531adad509ae119348f374ef1203c5af8bc019\nB = 152b46095d3f8db5e6e1a9e3f35c085da00e52764b261c3aa775ecfcd38572d2e86bab2f4bf29c2de4fd2fb6f35f66e8685714634e1be980773526bdbf9c43b1335c5d59f4dffe1a1fe2495ff9b7a3fae3e53e7c3208968e1ad1dd1dc8cf2e2415cc76dfe5df9e2e1eb63f7c7687d539706502d56247728\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5a3ad8d6f1b0763b77f5d40169ff0013de638b459e401f50f4cfb505565c8a4465e28ca1bf988071701dbf52ac456e01e170788ebd2b7cccb50dbfe1a65a89a8aee18b3c11986c9d6e6571f964f376f322e10a1ddd9310bbb40f14b0680385c40975aba43153970237c535c6b0e2cbf6bec918a8fa26cb2f69e98d77215c23a6\nA = 1d5c14b0b51cf31e9d97b7c49cd26097d40454978663f8a74095fcbf9c63e533708befb1a467f94cf599a41220ce13493a273fc30c49275412c5205db712d5e1832b39e65c150c3a4b251e2aab853e4ecb4f00ee5ce6982ef9215775a33565bde3ddbd932665aae506941d3ee31b3f9e4ffc0651f1fb4a5c6d\nB = -93cae5dd84584a2a3d88028d6d4cec4146cc5e350b4d92c52ba2393ab69fc1dba96e244f98e2f93f31230904169641aff30dfbdd3dc5fb1f3489d63aae1efd29335345a79ded546e42f2ee4a70ed932699fad17a771ba65fe6e689664bdd1135219aaa905c962d39531eba3e82c3425c24041e17858cbbcf2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 61211c706730a1b98c628b3c8cb070a42e2ccf9fc6302bb1c2960fb165087f210e9d93416ad9fa21634a05dd0723cc23b8d2a846ab7c3bc402999138433725e737102094db5792249b4b5b1514a416b80c804ecfb04653c5ab18b0a34d8777f6c2955ac66fef62c9ec2819f0e3c075920f951f86b32e02bc43239d9218580067\nA = -46c8c68f492d8f7ac7834f89bc76098146432c59b3301d4eb70d9861a6e24c7c9073f910108c7b35538a79de10640291b54e5755359baf47482b97af56475211573576e9412ee017dcf961a090a6ffb5cd995992ab68e3fe60b6186f7595bd9b8acf8695c4f7359cb2ac709f032fb993d16a74822b4935536453\nB = 46953f424d988fd20700ea08880e7e09ac22d60cfc294bd4aefe637408a3cacfcd0ea6822a679b68b665d6bebed3506d25edc83cc7154b83e22953f9d91157cebd219cd5177fede28c63a15710d0f92bd9e542a7586855bbe57a94c520408fc920b3f8d65b194af2b2a580c90db1cdb27ec26ba929de4573c6eb\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 50a063fff02f2cdc68edccc23976f4b3db99641073c85709626292b9475b9a988fb8509a6223f0a517dbae0cf7cd39dcf1e8ae75196d9f5008c661d8b5153cbdb9520c71068e4719820bffda4c393032edabacf99339e0cbafddb6042ef887b8c498e87e16b62417934015172e63e7457242b864a47aa10e203f47320f03c0e5\nA = -1740e8be7b4775725516d37ba643fc64203f3a61e6b0164d112af56666ad97afb0059c2c4981fa81d72264f8669db4e50e11865907655b1f669c88f5935cacf1b12c1db63cc84507af12cf0210f990994055d04d93f148f213e3d4fdcfe9dc42117c059897697914e3e3fa8fdbf0eebbbb9c3b9fdaa7efa0c9d5c93\nB = -226308f8fbb35b5f9d129c0f6a2bd3e5c272a408bf32020905acc6d02d7e506191e76a3a2ac47cf7a63e6306b256f489ca5cdf76c7c3eede175ee4a7acedf922955e92599647b69d463cc14f2b178b88cd471b8a1c1512caa66b6d5fd8840b98b8d070e6593136e98cce9643e006b714388768920a79944be36624f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 747cba0d1cde75dfcc0b2af9072c5027986b3e3917845870c73c452858ba21d6d1615eb71ae1b5a03ca44e22845d5432b368541b52a4bb02498668e8b99dfa2eb90ec1948d90564e6ebc388ee9816e329e1d8da0d3e2b12d901d47e22e8a1fabc37408be0f89e7a4ab0f30a03f7e2ed817006809e69c21104d0efe548165f64c\nA = 5fa76e37aaf0eb3d34d4f4c590e02b6c63fc62b1d4c9e172cb0dd82409df87ecb43a1680a2764f62d13a5e919db2db08feaf98d5cb92a859dd42bca1047ff57b8fe5974fb3ac11ba2c0d8e2203750f30650db4b2cbd31d07fe18c4df84a0dfdb30f9e528932c097e89d8f8be6ff029dd970a7d2c2551529455b9131e7\nB = 111199f91b3749f8cecfe90e9b9b6951472cb701beb39d63068c064cbb2a1e1d30736026f781836a52ad0d828be6c20303c6c0bd03ad664dbf6044a5bfb67fc20a049fd37c62ab0795d836487b883768ef7c8f427eb98e5ab6621fece77b4955822f8efd190c417ced398c221215b50e9532a869eceeb605fa1c936554\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 646cdb3ed472a7b4599f02329054846a8da173000eee7533240ade4dba82ee3d7a6a92baa3783c19dbd3f76fce6b5bdd83f1f229b1c71a6faa18602e368f1b0b9f8c62bd8c854844af85c2081924c9a153e27853b2a48147950fb614028e090e2198", - "e613631c95e565c2b9b64a43237fd4052089f9d1dd2c00525dd35fa946ca\nA = 1c8438247c0ca376f508ccef7933724df512f9e0877596f7f4ea73dcd824809bbc472749833b537eec01ab23656e9758da22ab8a4aaca1aab3fe8d2cffa6672ca0c44ac029c2ca6c3e71780c28c31b5f154c8dee782f6ba009a69d83b1a3a03a2d6275bb8bc3932a1170470fb7e405ae081f4770b535edf49f73a12ba589\nB = -e365c8edbca8dcc4cc11986a5a901e4ed0adbe89b0ab70a53aaf5821862432a1320cf1850b515177b630e12692cb025e3aa43e9acee0d8ad5e48bb15e9a3f34cbfd39d285127b52dde58751f572ae68ad98692899ab12d35e33652c4426ec60c5029e51f7e32ec3d2031032aa7b6b2b63f84fb0023c81d031773f3652cd6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7a3e22f4a3f7ae7512ed73a07abb5ce291bc90bad507a5ccc0c17185804b9d231b0ae2e72bf270dbd60170f34b240f716529a449abea0b3d98ea2890a4ce3d9e2214819aefd070e00201e9f271de925c4ba59651e55174c97a13a30197e46997c6c2b152548111aa98df120a617c54b71f8eb8b0c8b4dbd5251f5509fdb8a1a8\nA = -78a99d206b4f095847e9a21de273aa6c47034c9afd4c081a8e93c2d75f4ae5b090921ff5108c863785c413e2f7b4a361506fb66b7561b8b1c5cd537e90274bddaa4e91ce74ad81c6dfbfe1a34a631dbe455d74ed9d041a9183da3bc469bdb214d2ffe893f89c3ae30f8ab99c3aac4d2fe864b891fbf4f537745fddcc60504e\nB = 5c41274e9590c1ea44c113ce505931758f2cef80ba3b10440941ec9aa2ac984b29868bece2922eaa225555dde84a8334f1caede99091165151a39538e5b7390e81df757f521236314239c213e9b874e396a022f04629c09bfaf929a0e9fe0b0c7386b0541446f6a2570491067f64e662d8611c4fd6d1c78a9f3ae69f34d14fc\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7fd27b6549494c9bc860146a3e8ceee785ca03faa94b0ce0a964844e7871e813414cf3f111da49fed1ede5e71e5539f34173d41f9a17ed129016bb9b04c86487f5def9fe350fd4dffc67b6e181e3cb26378ea15ff9b9ebdf1fc86c072c82ecd8bcdc241301daf1b774af5f90f37e45e6126c5da7dd3753a1e5b366038af6ae31\nA = -1930548d105661dc25a5ee303b61b559c4bc1f2e28b2c40cf3e25f98dfe01a7dcca0f3dead6463b55a5b2e0440a651cc9e08e125535e081c742bb3b2f8955ae897909cfca683a4822896d8a4a7073c29a80571445c6a0d53d2efe4a30a79d2fb5d08c0f95b735a1cab17ba40d71b054c9270ba6bc870e58591fb1bf9dc9b7ee8f\nB = -3e2a4c1509494f94406e3843c9446edaf0a6060144637234c6d9ce84d70fac54ed163d77d210bf557bbea0404922c8aebec67a0475a3c7b74bfa2f226403ce987c705c712bb8eb0934c2b390a173c3836378fe71a6939e48d187b27cc7236ac115309fbeabd9ffd0396fb7fcd6d46a1dc683606c757ddc3212f5d2ff3f2e450fc7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2078bb5c82a394c30a287aedcfdc5271eb3246be05954181ae4f86ad2880ce674640ecd55c2ee3f4e89e2762139586516a28558481303e3071cc9ccb9a538f887553bf5726f3849fc41ab027fb1c680ce7dee3982587ec71b3760e5da6956d6894ad8c4526d8de953c0e681ecd44883a21f0abef1544fe601743efd3e5eadb8e\nA = 40b4ba1e977825b7accb941fe0c0a49936a8a47429dfff53502fc0680d705b9fa0efe003eea3ff0b649998fdbae8d0831bea7f34159aa4c7add6bc7cd56fea97d25fb9a6a10f4572c26d792b76c18ada19b0ba06b6142c420dbb40d66be669b7c51d8cd2a5022fe1a8aef7b60965c0176eee69c32ca5023782c5410adc1b15dbdc7\nB = 1bb2f18d7c8d306bf80ae1901115c8dc3d286baf537b812ce06d6872b61e5bd44f3c53d7f31ca8461b3628b255f85338cc325856fda5a6248b7c476532c1bcdf9713dff9932a50e52a9441aff96092d3fb0fd76046a8d88288d0cd55741083a1bdb20fc6e9c20e82490273354bd826bfe001322dde9a15763f2c0e6ffd2cf60019aea\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ef21dcee9eadceaeab13287d6e3c9741811f6ea9d5bd111799ae05260b1de2ffbc192818fa45dd7befc3baf6840e3b9d24cecbcb2cb1c3d653c4aec6531b941d926fb6692f548cf81526acd0b6b0289d70dd11ba50ca8de6e174f502eddf47e57440142c7f74f594a9abcb48ce1873df057b132ccce8b364de3edf411089d28\nA = 19d0109e0c47ad45f57b8bb8519265a4390534d2ea07f969d84ad33556518b6234d40d1631be3c3cce6d59b7be14750aed114008458f50a6a84ff75b4ee7e4b826ddcb2d2293842ed29e4e484260a92199c5c66367c402bdff0f1a8057127c6ffe452498bb352802e0005e6cb084663bcfa82783a3d72f3a2a341b8075983892e86756\nB = -81fce71491eda139ed996f6a289dde8635a3a257ad6756e844c768e66746011fd797658184fb44b0e3f3c5600c56238ac7687b5be42529d5c9b97c3ce10f3219e1e451bb2dfbbb44cae0828ef894eff3b52b8dba4c115c3b471984441045f2c2db426cf5f86949d5bb7662cd40bb3b3172a19ca3fb6858315d688f13c17550e700cd5dc\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a5f90344071790373044193cc4fd92116248aacf05ce639b6aac4461ec3ccb0805ff9876ef44fa71088c295db14fc820f7ae2c0aeeffca055f8f7238c6c90db706d02f2cc43b4960abe3ca4b6dec8bba55327b958e75c60c5d1f43fcf9136f12481c267481a725eecc403a16aa6221346df680560ff316a63ec8b51dc37aad6\nA = -7a54e7ca04b9a22e2b986e72e634317ffa20f6f4ee90353d559db3f3c1bc6b3b92ac6b364f6c5929090373962b49b59cb5d87554387761164982955470cb45dd00c4a8982dbaae3a1ffe700e8903a4a8e4a21eff9d00fa496d475e0e1a205be267499dacecd31551f8a9d437f37dacfdf5a2754f0876a3e02509b78674e7ea2169c43f29\nB = 652001f073d63ddd526abc957bbb48ca74154c8f9698b988178b3313dcde9acbb19ea11a935184fcbcc31e0117d8d2ec695ac56b5a71614a12cf90f21c8882187428755b6a5f11c314ac8b952ced0f65db0987f0f87e20b82a811599f4160e65c7418af7f33604e7b8952b70581e3e02dafa025cecda970d04383ee552abc620dfb9c5df9a\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 67f903e0e5623258826b681506f3e94cc0b086e262bafaa1395294aefc9f6b6323410a44427010d5e8d8288993973ad9939199b85cf02ae0a09dfb69801536a3fa6af5ac373add7efd25ba5fee6d8f040e97056f9f6fbb45795c0bac94c51ffeaf496710b00bc9ddd8e445261d976168771060c9bd9d83838a84ee9428f59d6f\nA = -19c695ee3a4ada840a7e3626e61047c5081867b15843ee9a6506ce45540d23ad25ff23b72f988bf26ab8b98363d9a2997773604f43fa732f59a4b16ddf3a45acdbc7976a1fce01b3dd55559c20acfbb7501730f794bc45fc09b1f035d60413bbcf32a83fd3c41599049a674f165ac5283c42aef213d777ae47eea960f7727f5758146efe5bf\nB = -210697d47beb73f45207340a183a729a1e78d84bdde1c7d8f80bc84559c4aa4572ab0e6927ea175acc7a268d05616201cb235e610d1012500c8ba9351a37bd68b4ec42227bea55cef5ba7d12ffb180873ab9d33d09e6e969df99fca728dc12dda6903169acbad38388fa9b001edb09056a2ee2aecfab0468822bca14a4bcdd3a4122290ec5ce1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5fbaff0ffcfb2330283fe59611ef51cf045bc2690e31f2ad3265046fedaa990b5d5060b3c38f17bbe8b2696e527fd77ead8650d329c2e0c1f3b2f5bec4dd85641022f3e0ae6f66ce98cde1a785bb52eca796ae45c33142e8264621ab447cafe988de926544e1a7036710128c42fe8b574f7ad69d830894237d95a55d1bc7f5ec\nA = 482db04e35f9fc1d87b42bc5efe25a049ed924f816e1b0f9c8ebe34bc771e67e26d6057563fd5d5320681e1207c0b0f4b7df547cd6d5be6a2e0f2bfb088f990b0303d0ef263cf45681e0e9a1147c29f2ca5251faa633ca53f6e0b109ba69bbe20c58a76a22789243d1acf128dcc936602e832a20a2bfbfedf963bc1027650f483814d7f5e6905\nB = 105aaf563d4c1d436c6a4552770a527776f40bbb844b7701313c5ada95180160e7cd4b7175ddb943e5a22c910585dfc184b52935f06b12c84b6431395f28af2eb9ccfa66b2ee8f40fd44d753c6a83d67a6f3fe3658fecc7fb2f4a8f357c5d244422e48a33d0e2971059695a59d0d39b235d5194e919facbae7623ffc92d771532b6b0cf771912c24\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0", - "a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a9d204c1a497f350fa1300cbaf682c947eaeba8b3aa0450c1db9120852a2edd2a0249dedef3b3746298ee42834d869e9f765ce987a2aa4712a1f35ed10d0f7ba9cdef938b073c3a526e5bf45f3510c94ff1fb84bc77b08e2aa50f5cc75e2f4da37a8a711f8aed5e92f7e486877229cb4ff2a4d0755029972323c0b51a14fd1e5\nA = 13fd3d7cc9d6d6821d2f2b1c40c8e070bfa85b994ee8f3e0baab544dc71328a1a57b7ee57392ab6d24bd85f9ea0f2a312148fc4f4b22c589e9a265d97e73c7a5b420bee180409ec179c438a67abf37eba61ac76197f3c9ea5edf2d4b8aab91e9bb1a432ef1f214c043664a51ceed1f2854880dd458ca253f09d6f6acafafec310774a672d07147b1\nB = -8c90ecd56d6c7cb129d1c9c26e94cf919c5747450542cab52281d11d8fbfcf9ea797b29588340d146cc40e77dce007b68c0c24356d4b75513b75eccbef6e22a5b88417cb6c516578d17d871e7d0957c09795f9a0f19b811db75d61c27e1827fa2773846857fec020f98444e307d3e52af501114b962ea705cb0cdf815109054abd00810dcc270d7bd3\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 57aef35a3f5388c810f576dbc30d4e4e5a39248b319b7766311157179d8bc1d7ef019cdd8c2c0175a8424abe7b33565afc0128724fa38f0900140b6f96bda2e78d7c803124cec8c2f2d6649afde4030c76cd33394fb386342d1ce97a4ecd180872134fd4e22667a687915bb4fda21f7e0bc9100ed8cd3a6668ed3a235d7b15a8\nA = -673bb11795d9d20a1e4ce8ae71d041705990463964505befce5949f895fa31c92d53f91fbc110df4e789b3f3f01f184c55df92927b8b680cc92864466ce5590ed2e98901cfb78b32ea79bf68b57a14cddb53209e08a7f430fee23f4a1475fd2640a515f8b609e98c760b4301747ecb61f1e6209b07455f1c8a7bb4e20c269e17937f39c6a2fb7b2990\nB = 46beea6005cf96a2acb16f37e357bc8975f4dad502fc3aefb4666344dde456c0ee7ea43ec493b6aecbc7aecc7d4cd107aa09e874ff564f5d59d7e12047b048c1da1faea36a7e2d02d0567bc4db41b54a75110626d13597db698fffd577a5810286ea8bf50625296ee8070419345fa269a354ca2eb47fa3108387f6a4b2c0ea3e779908a14469106eefc14\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5cdb7c451b2950c9d87638857407276959142958b06241b2010a9f93625f9106f065798f79ce5c534b9e5a31fbcbfc63cd200fc1cf10217096aa0194acb9043ccf7ced30d9f0bf66e0dfe27ee2ecc40bcd8de66fe2ed6f8cb0d874ff7b5fe71951412731fe4e19c34bee64c9312577b9e7b2ac08ed15aea753a6cd3e286192ec\nA = -1eee9d5d3854db52f9b43698e05d6a0f1d1f8df5f32884a775b25110309c46ec5c7e112eb64b2d7f948868bb9670068779b0a78bfc7e17860ee02692ec6790222b4384b9bd7db5abf29c46261c10d95f503b821a4694c45553e0dbaaa977892b916cb8990ac9ec29ab5c3d63ed77138fa1e95f395b3b233d039ab5daecb0296203166e9386d1071c61cb1\nB = -34587c2bf3473a2c5d7f3399d5ba2bb09be8105a0b9f3d8737d67b03d8b91b1c869f4e223d6246abd36d99d84052ae5894e58288a614a0da8d69f1aa57428632c2b059ba99315ea2f68ee210e65a741e94125ee4a723a7828bcc410aa2dae06ea8ed6cd23f66ccca7e85d2e071055787f230ee405e50d1519377cfe0cab4e5f97b6cb893b01134813a7c2c6c\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 95d0b209654de56bd7d6f74afaabed2cbb3247f449d80511d2d3c689f84c9b79587d78abdf0eb37f1b89f1f8dc8a83f7f9fac2c8cda1fd3fd64e16f5597b7f0a1df6da6db9e828ce7be0e876012bd52f5a74ca73ff8ca4611dd9f342bf77b485305ac28a1f8ac7538169f2bf3e4ff4dc5fdb9dedb97fa743fd8ac8791b8e288a\nA = 7821d4b65d529c30b8747e184e450cefb11b5ac5dc77905e6fcd3df64336661c82ea68d588ba616d23df485ff0658fb3376d5276027a40b392f47219edc5ecbf510cf0c5b431b02c65e5f432092f941d32ac5f71ce3496e403c7637f63a23b91e3326d01d2d32e99e0ab265108dc5e7919d3983839b3c7541848dbcd420a594e850e587f1846951852ed76d\nB = 1adf5c428f2a95c27a943637758d5dcd7ca36592fcb9d52ac0b7d27adddad5804e3edef257aa51c716801ad0c731e13c5dd000f11b5ff1b69c198f236695c1b2f99c0afffb5d084f80fdc534de3b0df4597404b50c7e784c3c55dfc9753c414d145eb0ca4d07e2f65b63f3eef8d391250a5500ef64d9bf963d7250d6906694e7670f92e3d5a7930f0f85964a21a\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 46914b197b84fa99addeaf55dd803182083a7ae34d6d4d3a55d6272af40a600563cc8d9f6b48110d0521b8b99751235bd5a340b1743497ef1cc459dccf5d6da970c4c3103c978ad2d513298f1fb3e68b24a9c7b0795f47d8f7f6ca9caaab9a9d80f15982599d764f8738217f9158517806fded5f3552fef8b7dcd2e725ee04d5\nA = 1c9f5f2a0d72806dcca92dac1450a50cba05b5dd571c2b3b988d33528d90ecc83444e3ea8df80802c30fbd5a6ec2ad9969be73aba6dd27e0dd2c842b95371d7547768916c0cb036964d041284cd323c8073095b2a8cb8797add5cd80f03595de9d18af8df7dee0d250ea7048faa47ae0131ba3f350d82864dc95e5829b88eeaf2681433dd4d58b2c6f70426af3\nB = -aa1e1b3cfd5ca0facc75e46d872584d55144620f849ab05931210b4e1526f12679bbd9cf00efdbd8863970e2abe8fc9fa7bbd21afa9e364e3c9e32f51fe66844fea4bab7f3b1bd278fd803f6bdbd0d296321e67751a0b894da338ab431871adf1514269ba05e0cea5558cd5691920fbc18237914f3dbe4b253f774e5dc1dc57023c080a3b90a004b809d237658ca1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ada55d93c533716ebd8c16e23603071950aa714deb942ebbf77206753d2676a7aaf61673c03a4db69d67faf6273828594d85e3c8cbf38460fa2af603fe9c1b6ce104854e7281757b26589f079da80685aec153fc5fd1a223004cdf30247f8398b8e92899857dd199d5d5c32412bedbf9d55f20e52895fc1dbd04c84cabfe1264\nA = -7d22392a8da1966e6cc5ef50d7409c614f8c8f8e5791778f68a00b4a056d0002707933043d05e48347bbd4d0dc1b6ca32a1aa4bab9992e7e620263283eb68d97af13b90a29c1b7dce39ec0b8a63878e8d65aebfb3bff4e67129e3b3725f999f1ec9ae92007911f2cdf738499661c5b6c9bf27712d0f29e871b17318e95c3d14b2e472cf9e466bea91fb71a493b2d\nB = 40279eefe59f954aa8c51c9c214fa07707b1d095f697ca40edb820401a45c472d1d7bb413eeddb64c14ce6144b4863fe9337ae4ae8698db92facacd6a56f3b33129c5b608eafa29e9d92dea620113051b926b80b75f320d7ca3d2ab597168c68774e68c47670458f5ef2ffd4604f20bffcc7817eb09c9057fd9989a6786a7e067ebe6724a89e7d1580f94ee4ed502cd4\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4dcae9def5467526b0ff071003e56f5537852cc0bde9d86eaed2c15e36e6429c68c061e12d321bad12e29626b5013c28f118ee59624ae2f35d2c53bfd89e6afdb6db79f0321ad5c55cab03e6a1a97ff7bd58c760d0e9fd7507de987ed2f94f9c79569fe7f03652cd53c67ebc6bd3c9e6c5672891a9d2ee11b300ed3b19753c0f\nA = -127f5ca6924851faa2340c4c8f425b1dcf41b313c5c2910e5eff8ef2faaeaa43305de2b3a65a75fe54c00fb30c0ce3e8007db1ea222521190ff1de6d0cf2e777ed61ce8211dc167bf115a77890d0bd1ca786e967a04f077c89939ce484bbb1c560f669aacf7756a4338d97cbd7f09a376d2dfd4d632bb451f52c03c05762f050ebbf112f8dc5acdd9b631292fd7073b\nB = -3bc5e9c352c46449a9155b7ce5478c771293599cd2dda58a962010f1f21d094aa6bee03f9311545e8dc6213f6aa73c08b55bcdf4d1d84fecb9eda35c83eae5fedee75b2d15a003f8a82b2b788ea19f7460fdd8f447d973c950b3b250a3022c19ff312ccdc86b6ab50c4ba627b15968c8a66d306bbdae8e88fe28c1853fdfb3fde92353f46b5bc448ae42306a4c91202f03d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 62a812e35f46e04b3afa7d26c8fd4eb168b6b64cdc839ebd0a46bf2a3a712af8e97380cdf0bfa8a274f7b73e887bb4cc73c6104a176d425aaf5352f14ee51ba549a6926bd8d059b8e3826b174385d4635b0c36df75a4e7da44c34e51eb82322b34ae00e8c712eb75b3882822bce5a2f2f5fd74355319ebe1973284c690bed2af\nA = 71c57b08127a956f0c17fd3c639bd1923ba19bfdb83c0cb9dd78e62b8fe4b7e0019cd0a6b73a334c622118f96fd6d91c1e06d4dcef8a3d0d6bf8f5beb", - "6389226c50d14d3947ce9f24f7e0e6a7befad2e4e92dc9ed8fbb9811d908c03ac074b2a5c67b67831a350c4d548ac70810bb5617d261a045e53cdc48117b9fe86d35950d0a181b73c8cfd35edd31af031178523b\nB = 1cda2a51a707f8c4d2cbff6337c3f63519705614c26a489b545b1faf366b705af1d953701b568a684856fd3186c035f878788f7e5dbea16b5e7b6e767cf611452a4272abf2a9c5e72b7251a1ebea5098c60cc5bf649cb70980b97d48580967ffe2913309b6b78cc12d91025ae403928851902dcdaaa60f5b323a1302a5ce114cbe174e3eb3c2fb5eafc44076396c23d53b028d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a9213cd809d41b6bbfc2123bb84860788ce22d5b91f8e24fb616efc286a218ae9652b42912a58bf8ce596a1b48e4c72f27e52c36be1940f7d2138eb895ee36bbb917a59f73e0b6c3266bf4759ffe2ffaee3f6179492658e0778bb43c4df4bfa1a46300c9da496033142ae2c1e33333fd7e82c5a14686b255e224c51aecc2a590\nA = 1cf4e2d5924510a5fd06ff4eeb94a740e430613277149993004b8de1a2b96ada54b05365f305e896df5fdffd3d7bcb54f9a9dba9689e5ad498012f7a684d083c31d7017aaaee720bbd42382e526a35d2add21d9369f7faa41dbcfe3dae426948a402635771a977e19d5c353ec7c1abd279975f2effc0b7bc19990154b723f2f8c29e606581ab9d3966702f68d8bb8065e9d8\nB = -cdab60f9b8e1add4c54427b638ec5f76b30654d3649b500f833b2943bf6cd5d8647549657a8ff999eaffe413ed87e06267b97bfc1b77637b57f29039235548a7569fe6d4bb16ae9c6cfd38c0b8c73aa60797d0d69b03d5a98314f7f7ee25df8b896ecdfc782cf8057f038b6c3e79c99df52f839fd4eff302ddd1256e51eb31cee24585782a0439da3db2eee79a58f889d8847fe2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4dde3d63aeeee47441a7e733bcccbd4f2e495ca3c746468e9855177f7672d5d82e51da8e268ac24e8971d802e25d842a16a6b8d76b8e46a7724108c02d38a4830453408ca5ced7093676a1db4bf4c94b9b7a9531ab7c26f8de520bafe4431a55a5f5d8c7576427a0f5bf2081b998b82da2e8e959f2ec4d5141b55e40bf6ddeef\nA = -5770ea0a75ff451fc2c86d428f2569884b2c88cb6d9d407cc22b191849d389f57a5765b83adcea21c350b37bc6d750d4859f547da22ea8a3698a5cb6154b946331ae2ca18e7eaace951dcd49405bf8d8a716f7762eb242b8bf5e4c53a662c906c3be89e53ddf7a706ee2406c7d0ac17b54ff259c1bd5a092325938832763ac4caf0232e80a016cd1994441808d8db7e546de3f\nB = 7e4246ad4af268695a51912053ab6628969af4fcaf7f1e97dd977984a1604e8c9fe6b920f39a764c27d89f75986a4bbc122f92ccd1860f24677cf346474fd9441f572f769daf834e6a00cbc027e15d6aa7ec2030becad41e1068740cde82abed768de7e2cfd325848f6063e2186faa76982b9ca73ef22434a28bd2e3a5ac477af50f258140bff938d3fa02fb904a8ee0ef3c1f6fed7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3d8bde8d0625fc46dec46fc657c49c8ab12a988cec4ec1c24e6f4d8ff94514c8d8fee4a08399c6bd23fb6464a38bb5f249591456c283325e343cc289c85df0ff2c1707a6e407ff7a24383b66ab603b75e2dc3835ffe9274eafea148f20764b8ca30cbe483c1cefd51f82dfb93d7793b3ec19a57f2ba03d884f345bcc3188fe28\nA = -1680dd51d8be6069c86ae157922d55df3b58ee6f53738677bcf7332d6e7ef304ecc7ff7c5a5e1f525459d77202f3e815c68f17f9a6bf358654a92f9f9acb252ed8e9e6a849da7491f26d0e33900541ab67ce966d042607258b4382b8108729a703b429babc34496528f198a7e0f814db80fad4900fbccdfb64908febf5e09805d3a3049c0f164f0bcdaaa9bbb06df8f05309be83c\nB = -2c6c6b3c89f6e1d1cdd9abd1a9706e4f642a25738aebbc97cbd60e1f4ad79b419dd54bd14f2bd147b1d8e9bfcf92faccee61a43dbd1a2c084bf06a2ca476b3d169fa2c99794fc827b7f4dd010c0534e7cdd03d00456033ae0203b78a7ed229afcec2d1cb96892eb18898bf53584dde56b4316b3bc5186d97e3a9edcd059d7fe14561eefe4881beb8519c1cb7c3ba22cd2e13d874aab77e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5b4fbf0445807c8feec7efa3c2bf8dd86b1070638f3c87f1e173ee980412a28847b263a266506e70381aae919ae05d306d3a67a6c1e72c8ccf1c27d6296526e87f0f436c98fd1391f83440b58fadd4fb1905a484bfe8f516661e7176a268660387fe6a7266ef02e5fad91ffa69247bb11cfc1b5c3a88c76b7923a26f8a31ece4\nA = 65fe4d55bfcbba2bbfbdae831aef3dc8c8746e1d04cea174c1d336974d81d026f562225b4a297b1c3b044ccc5dc9c830a805a399bf26c0369b52ab0dd2c0ad19e723fcf9f5de2990ebe5a1266653195a2aefd9a392fd3da8c22c523a362f195babbbf5329018e3b454221b3e77cd0dee79f612f86332b1d104aeae7d8d84ad06b107715bb76bce20220d1340ecfc666b2bfce812814\nB = 12f775dbabf1c112523feab443f6e95d773e8220d66fd87bb7fc702588136a048e17ab6845a9c784dca275cfa445d007e8d8383740b156df7048650f89c5ef1a84148488fc405898f9e326cb8052f626c8881abeb70f3a0f52dd83e3ae0cb82d178cbfe8c393449caa2a87e7c8e2901a87e276b49b6d012f3cbb65641add3694fed3e3177777e78fe375f3a3b378091bb8d2998286562faef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4f0af7cb0c4e82d0e6589b24b55528818bf2164d41f58505a2b302a8f677df146f8077945dad3790c323e19b37e3379eb95de8abdadfbe4417f8bf8da643768a622ad4898513fdbc72d3b1d2791ec9ff40634678faf0e17d6e0851f08c39405907db85b74937ac403a9a3a1004013c7bd95a585728010689fcaf63b2031bc8c0\nA = 156dcadeca94985ea8bc0d1378daf1e85ecc4c7f8b6d6c7a5cb9f9ac368a97c07e381004023bc575691c082b5e9e13a02fe813a55e76196e4ad4b0f9b1e089bb71a0d5c94254b66e3e645fea25d69bbc5af266e730482a60105306d664f0ddecbd76d54e7235979aa2d806b809b3468078b5d90aa22cbd2c441198d4a52f6259972cf3d02003dc39dafdf3581638e56d08c5181d36e9e4\nB = -9a54586072d093939ad86df11fcd3337ad7e9e478dcbefb2b89d7555883fe8565abcd5b0a9c88ab135ce5327b2a326db645bc7c0e3ce24f902544675ff9d946abf30302f123aeed0f4e28edc72758ffa760277caaf4817a3ae8615784c81896d2404e2cf47c06b09085cd0ad1ec46cfc1f04d0272eac29e774b30f19939d08c036b185983c93ba15d1d27aebe4a357b9f6a298acca3940d2730\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7c3ac09486a6fb518b98a9bc8a8b382bf2293e2c1154470ff7961212430fe2dd28697e49256b1ad8add082ee27b6ecc016b120e971665be801b720069d30c0a8c6ea4795613017e8883e5c0d0e68f982c328379d7a0afb7825c553e087b33e9d78f90e0b95a6597076b8ec2c1d375e2143bb778c318ca0680a64072cf9a4fc08\nA = -71d8e7ef13d63b4f417c01ec1241020a8ff4c9b2db531500984fd3e45d22b2bd581894c8a248ed7cc345e70a5698407df8f0e4ac71ed2c0d42122a4f92279346f463aed899253206786928a0eb7c37f2e51e1cde7f97cf9288d85c3ed7f49e62af0bf9abf062d2c6544d83b9d3438b3881e0d07b1fa0f2a4446fd43ab3b4f81fa2cdaff199c87965e298943c68cc15f2f3f3225efad68b73\nB = 64d52de221f102af62ab1e9526935b005c81658f8fefa019bc58e641023fa785798ed0dff8f7f999dbcc2ecfa47d5314ac6676c82170d6f2b18122c17c1e1ec1b9b54e333a184a46ad35b2150c8165f0de19a24b98327715e5a641c1b6d3ff9d247c89c8749e775e6fcf5f967c6eb5e73523d4f1ec12db7321b14398f26201a364e1371f0ac922781ee252c6d2b3c657ef259ab73cb7992a370598\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = cd08b388ffd41d0aa29a3dbde74106c57b18d325be8f446a2d9ae95fa4144037dbd41eccd50fa34096984cb11bce555c117c5568d76a8f79d308ce11043fe2413d37d6aa60c366af6c1da93d525e4b2d79fc82c0a53ed62fbf72c919db8a3ae11f5ff8057d7501f5f6dfc9ae461c308d21919d0de9e31b759d1d8e3526fee58\nA = -12e58708c30c93383cfe6e99ee3c5caf1900a7e610605706e77d8f428fd59db2884f5021d7a382cb18b75ed22528961cf43be1c700c581ceac3877e83eabd860583e6e94f3f2989c179ee5047c82b53d37054c9cb7ae08be60a91b10d49510e9f0b90ddf89f93790c3e18cccad5a9d223c605a6c567550e2b4950e184fd97dd68bf30681d3f9c585365de2cadf36a43f5a5305dae555396dd50\nB = -26ea5079ba7ed137a14d00d413d6f818e911cc", - "183c88764de4d91d7a9b4cc7af3fad703142dc7905992eb8bf489f6d8231bdb25603ddf3c31fda8bd9bc4d78835f9ddc1e6445037f05125cb1ccd92eea2e927297e5eb915d5d965a25e5d58feb8d79a890e6036c80ee91e7469d9eb672d7a8db68905d06f5981fc40bf486575a067d35cf14ceee3ccb79b72871bf8f52b92e4910ab17e5e59ab3ae6f9\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 34714506322dccb91308c403c267f1ec75f80faf3cc4272dff4a84c13eb1e6133af6681387006c61e7e087046b64e7ae74eea8a3c0564a7c1f381e1c940d92b2c766fffdaa7318d07dbeb877943a73b50517b49e5117778b8a60212284fb92f29a9f5304f8f537e88acf8afaf01fdf64773f988cfa9551d6884baa70587ab76a\nA = 638b7c549ed14256956bad532945ef9e11a50313172965386635a2fc7db79deb0cb5c157e9854117c17f1509d505d01a0e138d2e510dfcca45b4f7ec968b5214a6699b61b8ac68adf64d5394f50d577a154c013612090e2045462160d1f552592197d7da78e03491ae284dc9faf643805f2674af8652bae93ff230fc3eaa833dc62781e5f74d0f0b90290d51d481b0a94ae6e972197c6e84ad7ae\nB = 141f62297ee88ad527fd1e0e09d9ab5dd80e17b32f34a674a27b00d719839701664ccca1b00da2613396cf633b0bdc4482ad3a0c3e209eaea7c22f33706ae44155f527c9ca4e341e651760d1c39f65d5e99e649d013730d2502b6b65adb8a73e6bc734b7d879b430798dcd53fa6c0badd57896cb566d9f1e0a7b3a9161e9808e762ca819330ce9319dbe7f49bd663a9f57ac53d65c6851dc7bc4ee66e08f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7adf54c77eaea2a1743bc5011ace45b7651846e77f90402297f117d8b1c0377f93f49e92a2457f3d3debec3022a96c74c166d01b2279553ef518ec0e612bd7b382529184640c55b89255b2679da9cf370913351592de39f804f1724de36db90c045fa644e8ff20627f67d6afd4546f00d7af093f668629f9a06c07fab5654ac8\nA = 19c491d5b55aa25f2e18cfb7fda18ed4b020e3f63244eb9f6c4dfa86eb8a70875cc898e305a7acdd3eee081300edb3e4c837940bbc1927f5ed9f651e46581639e133515457464e9c451390828e5e7e00a688daaea74620363706cb69e02717489ba9ad05774c424c18e295278caf4df4ced80b4cbd20cd631df43f2e16ec0334564d9dc03dfbc7111e4252504fb449d5a25cb13630b7c0c565a82ea9\nB = -c3f765349639beb80f888d9c8b7b335ab46b55064ce2a88180c80ad280c6b7314df52b7e73095dfd82896e24604854a48121353aa1de663eff07882771803010005905896357cd5a56a59f0db0045f1aa2c0b5626e132c169abc64b9893f95932f54c1d8cc25f215a9ef6e4cfdd6dba85f6faefeca81793b2258ae1d1427e81e458482aab87f6563abf435be69a05b195d1eda90146a8cc92748ca6f798b10\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 32ba5fc81a7747c3d812cf036bc0edc49f08824d53b91a65a6d41edfb1651d99c11ccb4c074d7f04e652276ae3fdc8d6eedb72c6e46cbb1f7f4070dc9d179ce3e21a3826f7dd2c27943a8d26b192d7f5c4aee9ba0647e406133e3e89c262d37cf468aa3ab8c5dd1b8900dd06cd600abc6d372d9408497d9e20c86a9a6a4ad9d1\nA = -73958019a5a52357b9c1d954c9b14f51ddaced32a4d7b7c95730697cf90029564118ea168d23a54381f7bbd6718a6b662e4c87410e48ac53b7767148582b0bd6a3d35f488e7fcf2b128e0a58b5d468dedabde4d624f4a82e808dd7b175af0d3658c6df1ac0da6495bc9a8dc012f8de55c2003da9b2d478e1a089fab776d99026684026968fc309dae46a6ef2412039a8207c3084f96b4e38e4fa01d131\nB = 4330fdf00bc6d13ffc267073b68aea7419ebef257d63f8f244accb9ee46edd04fe5481292de69d377ba6b6304804ba7ec0a063b42339e6e37867261b9945ec705d3a0029c6f499420e02a773476546993b3c5e1efc2417f51afcec7145a9c2625496865c11636e285d4c8b053ffe66887333c51a712fe9c8ea57606103fd689dc88f1fe37dbc33ae4e92067c5bf51b53e2f8205164c800e5abd677c73949b00ef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 69b850a99b471003a56931f7856da357a2254ac50ed81dfae019c9b722b95af16047a0d5422cf7ab66ccd898e85caf0e03e74cc8a5a413661e5da483b3f0363e63a7031bb30626c8f73d6e99e290071094b7fe5bbaf4d303192e59acb5e53fc7cdee78576b51595d9f7a25ccf3c7f8889de68b9deec167778ca27ac9d4c71c3e\nA = -1976b3bbbf92acbfddbc05b5d9e7b62a7666b239c1e6270db7ec6dc2929bad1024e745b897840853d14cd815aabb01aed580e1cc66ce37f9d1cc4c9bef8ddd35d28285faa29f2003d2a4623ead7d73302ea9f380f16b3fc06b7c2b8bb4ce4c8b03bfb6056a61c620e4decc6048cdda5e2d3ed8a13b779b8829e2bbab91e9f6b0304b1c08bf8fd85e0f3cd7ee72255e5342e077ababdbb545d7f809bdf8145\nB = -2cab554f7a5d21c499a1025f61e6c81ab0fc68a874bf60470cfac57425a451365be62c380ddd31f6e202f29769e2b6106868da7c81522e03fa6f0704522a5f8bfadbd007bac65595e149f6c585d7fc022db016bab32819049e7547bf85d4232a7fe19084907c528e7eb0434f2e5a375ad9b7d463821bef2f6a721a635252576c176ba42519bfa5d97d0e47facb4426aea0d755507dac81ccf1537b1003ddbb0727f6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2ce33adf34f2249f8a2d2e073976cb4c78b71414e027657fcefd56fceb022a06c1969dfafd519eb9e2542662c7647102f5c528734dd005fca666be57b46234123bc3db286cfce07bcbb399eb6764daf2b9aafbc2898a5ff43ddfae849c7549289640edc4ab7c4b9fcf5e159623e5497f509ad6f0270a41fd864c9437302ce380\nA = 509f5d5b160e923b4fdd72f4d522a713d780daa4bfd10ddbd62b26497a2e7925c495afc2abf0ecfcb7980e588f96c4078bde51c7b2c19d86d15bbdad5de72fec2e0a284dd693ce0902b40e54af87ac5a5df38ae6d1d882ea6299fbe6910121ebfebd06b454ec5f855bf3e7cd544a4b0d9a764428662e824e2a6185723534f5e6ad829734347d240c48c2c0f8bd6be6ae8a495a9e383fbc7402a4096b8c2c214\nB = 1a3b7f55307031609afc974857a6cc75821e73a1a9535bd6b8e141437c3fd4a6871c904e22c5d9289df7525ac69a0341d3620bcfc5f04b38ae540e26beadbce0002a8a8bfd0f6a270007e4c52aec2fab11fb2a831b9886997256e4b7e7ad3b0ec64c0f31fb0d637869143712291f5073a5756466d7c82c31e08e09683478229bccdedc2cabb7e426af9025185d8dd5124e08afa4e981236180e0a390004adb7918de6ba\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a81fcf9a18ce476a839c896cc5d9b639fb1d74610e2f618c25310147b57cd77806c2aab90be7be4ed10f0122baf9b862b141ee8e4be5e0c23ea776267f14c31e50b119bdd33f2b41f6a4c43d35bf6f095864593e0d8c0f1fd4656d8371af844d197308bbff14e5a28b7181eb6e6a2b31ead7361e287f3b4550ab0484bf7baaac\nA = 19f1ce60ca50bfdf8e02313f1c9a45496720a2ce467f1e8bdedbb32525d762878b61476989c7f6ae8dd29c983ea596e521bd4cbf74dba4d505dd9ea5df423474fa9725d5b65f1575d26ead95725e2a59a6c8a5397ebd6b54123e42bca44781b84c014b8e5d2c1a86cf34d764b242baaad5be285cec72ba8ace808058a0226c04f95eb2b53a828d0ac41e6b40e5a4c4092788d9f7e988752f175f075d545f421205\nB = -b115a1101d97664759538d22154de4b000c008e551e2ab10ad05f12274b10a4cbfee762d232df5188fa1161f37ba61d146e8b95fa715d98e016da8beb0600de65216cecf8b8816f6e7e73e2a2bfa7d0bac74b517b906bbc43357fca69de9cb5507bd95205515b97b3a4d6842f3d7b09606cce1c7436c462f49dd05e915d04ab6fe2748ccaf025bd5d19749cc468d228ba43452ccc479c146ac6d781717bb9966bf3835dec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1473f092540ae30de595666beb33e430cbec42d7a28d4f7982e62f58025cdb617cfc33f1e5ab93d2ebefd7345561b81271bdc50bfbb0db6381dc0ea023ff7c72605da26dc7da2b5664d2ad7967426ca97b3745f82528964bb68e70087e14dcf2d71d30fa0d1f7b3f10b19b357e7053fdf22bccc5188c6919eff1e5c402b750a4\nA = -68f280cecc512d51ae534f30aa198cf7b170c346c1159fa9cf158d0127d43e50a8d4704ec54b8b4295dd7f51c6771cb5767fe0c975414cbe6d2bb58ae66a095e8832d5f443498b1ade1f5bf249da58595ebd878677b34e3b4c99ba6124e2b71d86a8d99727a16746469de51b0a61d9d981459a6cebe206cd36a09f00ffce7f532e2c31999847ba000b9e01a4b84f454544b6362a5c093b9abe9d583716f4534f2d", - "e4\nB = 5b79684387f18d7de6eec3a63d737490dc2a46c0616ec16388dca2be60adcda11ae13063ede3fec177171a51dbef430f8c4b3f6d297b9d6c020fc44e3ffab891d0d751d033fda813861bc067c181118dc613335ce89c5960f952e5fd28bc72c41b7b6e374ec29b837f1e00271cab646c794579d315260921dbc3b984b86d98b8f8816aca4f16de50657e4102f34d9e29ec3a03e0da06e70f69952339bf2ec4a7e74daca82239\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5e4b3f4aea7115d592bde9bf7c6594fee77372ffb19f7745b4de878a4024f81e8290c77d2915424df20004a7abb64c214104a3123e7c8f230c159ccb99bd937521b433dcfb065b186a685fc40f9166bad9380a02e297ffd6a307ce8d2c8f2f1330447a9c06c327b74f3cfc2e98f3351a8b385bae855941228969d1c29e9da3e4\nA = -11c1d396693139df5bd91825c119d1241c3f57b7ce95b46472dd82081738cdeb0868d18eb7c8ee7808016b3311f982adebd5a2e5f4e201ec4a34f3037d260fe580e771222de5a1a67947a4552cc03c5c59f9e60e25063a702ad3c3aa43f061a22567f938a91f1dd697c3e3978fa11ab1d65030bf327f8049bda745658bdd4ba8f3e34b060c6a2c6c5a8be54c7cb5f6b106f54a37d2be9f674f7747744d4350b3acdf373\nB = -25a65b6acda692ba3330d70dbc3ea4dfe208c0df358c50b7872245a909c5ac19ec568b1a1340e1a094f5b8e7d1e3b7e04bb4df002558aefd4540135d62d75bd5ce959128c1300b9d98429d7369610866d98b22c345e531f2beb80b042b6ad48da077043401a82e223e9e529e7407bfa466dd2680973006d047d837c26a60cabc36a7ef538f603ba19f8e923f168ebfc3834df8f77a559c9e0342e33df245f551bb242e5a66e5904\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 47872b544fa0425981ae17bb450ea346135e6ed7a9de0572ae14a6e85e8319f27cfab778cdd8cb5f93b417d9c66ae0fb7bcc6652620f7f3f74acc2bc9f2c090129fa8315aeec9ca7adc5356484474ee803883ba4695d7bc47c87eec508d16a15150cf3f757c4713de71366e958d6af045b2d282b6ce96976692c80b1e0b6f846\nA = 7e8f55c040862f12d8cc6e506608eeca65ce38e9e8ab18ef7007e3cf0f1c9a0696795bd10f8e1e1f55bb4f4f3a35c2e0ad18289e250571ccc26a961f730346efb1e29fb143ed97cf72deaab19834fa2e98e9c12ae4cd23b9c5ecef4a04c439f7d42e110b30caedc4334372ca24cfe4171ef1430528f7b57bbc823fd606fbd30915c5817e6c57c967c4c404a0847b1455da17effeebbec3f9357358e00001239aae209228f\nB = 1cc00b95f6bd3abfa697400c98110725a7e109aa9b8cbbe9ae16327c4fc8e5bc93afc7a94da32e98e85e4fd5eb545192c73007d97a4e84ba64fe187ef61d17f0941e165c9fe64c7b8054e24dad30f92b50d1f526b4bb031e6b1b9058be24884b170a145212273c51692b71bc57ee53176d8702b975bb6ba96284b462da2ce38e12d86b342c7f4d3cd489fbce88a309c7df1121d7bbbaab6814cd1e54953e5cc46813ead98f02360372\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5d193b085e57c3f1e825cf3b36c8bdc936c603136bb782a244b04a79fa713dc7b08436b85ca3b483d2e100a012d6430679b30c8e4101c8f08ca0f9010dc0f27fb37be842054dfdd99362e03a7f55ae58db7b47f694bd35d91a58975ae1f255c41617e773f91c2640f768bc702a213f073682dc761e056b34c57edd85585fe04\nA = 1bb1c759ea94b61a1721ef5680f42af30fa31444b27591a03b7c9bf5b90845ab965339f463a78bddedcd62fa21197c32d6850c61bae195f86e1c7a23e7a20dc618c59ce3a1c6ea6306c0b01b11a36d0fadf8214c36a133d689438021ce7c78b20c85256ec607360cce14f139513d9f3ea6eab067b1ffd0935d7c43419b93ecfadf2c5a902b7c39a69bdc023173bdad574adc77706c1a666d66f69578a5bffdc7cd6eee28ad8a\nB = -e8072c49cea603d48f20276df188fd2fb28f8721d578220cef7db1e56379c04a6b372e56a047cbe59ea84ad026adc5d0aa930011db63bf4959f15781e060e0240dfac0e2a2c26be12a21e5650d12140bb49a2a8e0f6a86e4b1eb79d9b8aab3202bfd339096529170cfe3e0c18263128686bd9305e92a3c43e1523f97d8a6a2707773e3d441da162a79089c9ea1e094cd5a23474121188013c8c287965a5e77599f6a7d64174b06cc165e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = aa79c899c2b9518857c9e4f96523a44607c3f6a97d1f40d6474ec79deb2feadd955fe92d789df4d362c828084559fab56b5e33a971abc5449208d31671c7e220c5945886e33ed1d804c059a8e439a92524a785076f9730732bc5a152aeffb5b9ecf3a7e4b55983016355c4c29827496fd4d7e6532c270cb9ef263573e4c63074\nA = -41b326c2b86e7ac14a2050bff67bb5bf9697f02594789c4a2b3e8455df4522546278d0620f28a680f6a88ab545de5829305485422f4e70a5ebf0ad15508dfe3f16ac556436d8fe8a8cde83ead549d88e0bb24dee52ebbb49159ae71589d918d3fac8011cfc3afad613ea09173856b7b79b55a2e43e0f7cd21eb9122d5f6a1fc5408414f5aafcff863b870c67b740256d317a0c58af9a81d8025a086a1f3d79f7408d4bfa06b9dc\nB = 4730f03c389f9bdd92fd864177e06140c9dcc02d01fe7d37b51d44de140696f116d11bb67adf7db797edeb7c304386a7f5e37bfac46a5462a6d4c49b1bc034c2e0dfa56f14bbd2a4bfaf86bbad4f6d0dfa13c782fe680847d4b43373d7137f5c2ebe4ad58c695a7d4c407bfd888ce04abaaec60a3fd33db10eaba6b6acf0e16cb61d1beb9212c2b07921bfb5595ef1eb389200b356eafe8b5288d8f0e2cf252b38301de65190d56bfadf57f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 23f9850dccd2af799f18268c3a2918a69019513c55268faf2477c50677fce277d8ce58a0cc06dfe389170faf5f0ae13ffc4954c746eebae66efc14eaef2c2ac9001f3c7ef7e32fdc31dd725b6a8093e33daa6d19808908e0c2d3e7c1c58e0fe9ed92f4d7cf3cc222393ca4f95feab5d34fe29116410a1882dff7cd92acb87590\nA = -10a75953e5fb9903411869a2949f8f04144d6e2d61f95704ff55a02f40c4f283add405353a68bf7d6acc1b8cce738f0c6f9271a538b4c688dbeface58eef0a0a1d491a9e66958750db97bd01466edfd245cef03bb6a3acb81acc63c38538e7f15deefd15afc422a8641c357c31a069258dc0ebb63f06094ed8fe7d4d420246b40302361967c81f0a9ca542fd1de01967514ff2565de7ae3b4a200d63feaa22fb99a251cad66624df4\nB = -351242b6e6d0122f7120deb8357c3bcf25d221a15f83579883bfb4dc2e6099e6b7b95fd08f6e573d93354b0676f7bc9fad563d6eb0f3567ef43efe3d874b9c7733e4fe1ef491043e1f80aab6094cc9b9c236570972233ea74e8779a6eecda23a65d08d878850cab6005159265893dc0f66920a12c26dfb421ec326a1ac09e9ab8085825c31aba488af02cd51f96b205c50e692dbf2d844ff0a989c3ba9f1c2bc7f2e7dd9458a72d310eb28d490\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 69c7fa326630d7de69249807cd8bc55c9315acac26fed3caa3c8a9c6b51ee96a7dd0b3bacd5cc13c15f199e268c5eb91d1ec36c085f83b437b9906caa6e39ed7bf09778610b621426cc8d36d96f541d0bfcc7693525d33e0c2ecd77ccfe80289a11155b37c7ea7791b5c2be3f9b954e230c19d746575afe9a1a3a9677d23c5bb\nA = 7cb78ca8e5d903096630744c85975719c16333e2e44931956d8c45b001d35ed4e184dec88c9e2167d2f338fe6f25540a144cc419590a4ac7caedea3bbbc565365d3357baa62fdccef2c5ea616614e0bff60e81916eb4abde0c9725b1bf6869e8b1e11f6d0d08fd712bc68003e55ed462ad4946f7f982e663f65d45c07c659d9620d5139d2b3332a68d33aec36e21716a3b75f44272a19f860e6ab3864f06def9a5ddeed340ac0733353\nB = 16d5b074e008fdd30e73ea95cb5fb87de806319388b3a44f33c94d38be0e6f1a92103dbdfb3d23b6e1d19bdb29ac14833003e9482cb7524d0d7b4c377f4911e3372f2cea6f84c938d84e3994e80f0d68e7e385ca29e02f70294c921dce7cd3829c5854ce51d1f4fcf7dba910b51b48a3f53cb1f187182435f21f6981cf8440f9c8287a9749c92c0304cc2bc91eef32d8e6526be802de8aa16684e8854cb0b67d9f7ea00f6f0145d14e3c251f70881\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 72192604b2f3f68b9ed3e261120ea52b06a05869f6abd21828ce8abadb3a71c360a14947bc738e5d1d530b9636d796f785bb44508477eefa80c4b77d4e8e35463e15ea2a48c682d3288c5abeb66181e4bed7d5b4e0db20fdf5ed68513aa5ae7e0978ec1c4646368f206636ec90e808817bd1d03acf9adb9ba57dc153873fec11\nA = 1112d291463b28ef45e879412e6607a3e20d50", - "dba5044e71883bb3cdfe9bc694a577fd7d896dfb836a171f3a4d8fd025d3a979b43e41baafaf7b535d9050e47f4880828640e952435648960bbb74a3c25dd90bccb3fedd254dfc0f031d0e8a468e93bb69f771ed35f1653cffea1a763491fdf6efa21aefc287cb611f5ea0085f64cc3705c784f87ce00846901833d01a3c45ce047d822ba390b538f0a24720155409f60ca0d90e13991aa1\nB = -d553fa2dff0265cd9d083ad097af87a99af3d8d93a9f4c07440a28a427082004ae5c81d22bda1dd2429f540de8df175c1b4d0d50f0227489ba570b28baa35055df951d05b584ae6b051a135d7eb2a501b2441f82c135a8ec0eb81d379b96ef8f2fd526ee62293bcb934c76ef8083727a4b28bbfc9f515ebcc2bb7ed9594a106e137ce94e9105b2e2f4776aa9c6abdf426a181181fece3251c3ef4f8eecb634e6bd47c5878663fd51c74a66b92713fb7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 459e19faf105ab17ff794927aff86196b3cc3461e69cada53ab8c8c81e2b1820408421ea1af6ae10257e8cd9dc16386906410761fed62cf9ddcf0da2a92800d99563fbb9cb1ab0ba46a17cb9dee3f2b68992c2b832a5932e4533fbd5c4487d870f3fb5d7a1c358f4aef02993360915a9e9cfde234df5f51c761d84568400b618\nA = -7a964c62e38e4124cd2bad727138dd12a086a2bf01c095b078ce2f81288d3c8435ccce0c8e00229184091130989434bcd107a3a0787a2f5f4b0e8c23b1cee9a8f39ea279fb6081efb6c3df1704fae9e87d63ac6eac4c6687b3551ab7ddac5ca0541e12047d04c2fc760fda0916cd2b585a90d25880fcc1bde8f0a1a413969938d42e8b3b5f73118798e85b901c2e15860e29e2ee8b1c95336b97dc10a21f5300e0352adb60b40a8a99333380\nB = 743ff4d91ea3e0f9c4f72e5daecb4fb00b15b86e30bacebbe4384324523d14e22abe29b00573733f594d652a88d98c987f8db08b27b4dc68577784fde02dd410ebdbfaad9e9afc6a22a8cbb13a780222bd212fc61e38faf409e940fba35ed909e6938e83b0fdf5b5e3ce138604823e788efc3aa0df924554fb70fd2faf8249e17a827c5d85942005b328bed97e5ea1f1810219d77f2fe121ce66518e37c84d64aebda3c397684212384deebd520a776b95\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 183950095d9424b0ed09985aafbbd2e5d64bf541a56b68b42ea8cf9b2c051615ee7bb6c0687ca6fb0036888fbc927cb7aeb303750871442ff2c0087a95f4efad568f48b03bd2b9a9ac26af8c259a3fa97cd2af7e3d8f36148c26785489cda6c00a21e7eca219d1f41b2e82ba8e2c1cd752eb08a2fd50c6f9077f3096e2eba05e\nA = -1d2fc778cf44c6992d1f3a056860eeb12f969358cadb087dcaebf5f96bec42bc0aa98672260adf1732da057e9e0d22081e33f5fa71f248cf89dd361036ad58692637cdfff584a191279f178242ec0ad397efc52e99462f496caa0f3133c4238aaa877fa7094662f080eb284c4cbeb992a368c2d157ac5c8c9160c167716406190fa39ce0abcdac52c8020969b87a4f84bc09a51f7b2ca288c93b1aac64e19623a7d9e69976a31074f637e4c82aa\nB = -2f188f1245b75cd21d052ec76edeb5881944a143fee31c67370fab0420a748f3f1957bb8332ffefdeabd0ca806169629f130c86c99bab490a9668fd8200f4a9b1704c589e75b5c8c855f133d50b2ce06191875e2872b36c78438d6032d53004c047f49e4cb81e19fa84da16d053e6cbc7c8eec0b9129a8831eba690e0542ca3fefd204258624e92844c8b7bcdccab986475a47c8b22e89079ea6580ef8f496099cc24dc2911dcb1921d1451e2163b55bbb7db\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a02c38d5df9ff7055ff84122342ccdf6ed7f7d54fe8227af091371f5ae62844645586adaae99c11f4ccd828103a81471bac72dc20625962e41d603e760591bb3569a21f45bf062b86b5fd1c617a4769a4d767a0ee14d104084c12ae875316a8f2be7adec0104381dc02c20b5851efdf7d4bef0d68076975e0ada3e58e101e8b4\nA = 5daf37d616da184acb278a75fda4e4fa49e544eadcf373c054b203a309ba198233f2285a1b55dc92e05d0213b26c82e261d8383a845813077b2e1b5f4553400f09410987c8dd21d4383e0f05747d0482d1a89f160a5220b22c78393873564fc5b1e4d5627ef3d4a05612709f301381df35606e99560fba07a917d7ea7413110fb5a8290e114d5200cfecb00b6c53b2ee29911bcb2fb2930eadba0ab9dfaf46443370307d9c3b61a329f0b8b8cbe7d\nB = 1d9539fdb1afabeb9be6e774dc7c7cc4bb4fd63af7abb557a5fc80a3fd23a4600de3c7fae89b91f3d441b61d3e24b2fd3d7803cd71620e7313917b4afb89ef5171a3d8a68c3c74aa3dfc8058d555eac429dfb6db40a9e0c25aacd2050418d6f32bf21cbb76981269dcd5883178d4b69a931a0338b93022a2ed0f78f3d8877989cc406f19d6d082ea344309318c56be7946412ea0867c78418ec32b9fa3a61017c10939c9345021133116933a3d1eb86a3ef16424\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5fca287abf1f487e0ec18c230860eed4a2e550228b1500b1e33bcd6675646b5afe505b55073129f22352dc2b113c584ea1b98808214b6916933e90e036b129b61657cdea9026e1fa087ee300e055ae8f94ffca933a2d70453ed220468a5a3cf1a65d81eca11cf570d7d038722397f487af60531f24a5f069671354882c8bd2c1\nA = 1d9fe15171dce97475f4ad329fc8fb5469fb2b8086e4b01eddb6ceffe5324cfbd28d791705848569739b6758ca7e7d7d49adf0c11d891b0a5879ca870d1ca5ff475513322ff218cd26024f97623bb8a53084594e1fd64154e1db702522883fcf4c0d677a7fe90096fc76dc3800816996308d8f0be2dbf3b879f8a000c0ac534511437e2ce2d7ebcf42fd1698a829eb846b3afa581c24d5bf97abc6e247f110f4e872a2474e3acca6c8c0d518104c3375\nB = -dc0da8f7adb8e9f7b0e3f293cf623528dc8e9668317910417e52301c50c62e7d30e77ec7e38d6817d1f5a93e851f8560f642f23a0b9f836812d27b1b41c0867088a3108332b8711047560052ea30c8840f03a25c65b227a175d8f340095823788adb5bdf2b7ebb801e20f6b6435e154f78d17b8fc4373aecee56ec7b8f5686a7d22c8571797fde85cec884d45ddc4b1f2cc47ebf56a879bf286f349a0edfb531168b733d43de3b86b49eacb10b06a432c96c63440b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6222c1a14c6390d73944cead58eae5e7a6c19d19e4563c36cf624f5b61d99991bed7dbf6a0723abc56469eedfb1f7982987c2c7af6191178cf0933ed5f191b8117c9d726cdfa8b82a2fb25ca5436023f5860aff5fd482c611f134569ae87395dd99e5e9d400b5ab1e3064210ded096411654518110ea45899f4be2516e35a229\nA = -7f6766be6c6ca9bd1fd7ea1f80bfe68693f7ee4b5ba2946846839060d6028eabbb9079a165c1a07eb6a01239f3f14095225b8617753a1cc3d9c1e69b516d8705cfda396f4f0d05b0944a0f08b478d261e968c06918914ba87c8e7b7adef5cc2a875917d00585571542af219bd726e502b7f3f0bdf0cb1dfc6796be2e22e8ffb5b8bfac7e15e991022974e75d3a5eba214ab8a1aab2fcfcdbc6ded2abf834d1899d2e3ff94bad9c696aece045212531773f\nB = 49c6f869745983cae44d33cb7ba141234905441ca53172abd1a2dd8bfeeac4b236605cd2dc5b04ff9aa13de84872145b935b85479136065d2d57fd15fbd97480c25c6354636c17ffbca33c9319d65e82523e39fab49321380a130fc160857a451a69b1d0509d5718a9cff8b49c2d677c1f66bf77333d2511f58d3eb2fb47b3c162cc9be8b012d8df70278f0e21123a69724a1f126369a236d54da026ebe222c513f24b577707b5ab4b90ab0e22b4e38ceb4181d4ca101\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9e9cc8c5342dc6d6daf55fc9aa9f79ec18592e8b9724a66881c379245c91f06a7df50a6ba0964603a6dac97e77a55d06efff17c93d5faf107fe65788d0f56483915f6ea0f1ccbda7656eb58fc032b5771600beafdc12c2076110a9b9670bd0754ff6a72c5d6e1a9e4e42c688e1cc96d7aecd815bdf5dcb16fcd1be1275ce7282\nA = -11635fe16dafce21efb1c599305e9a16eb5651187cbf054cd9d911c13e8eafbb738013e212f9c2b3662ea15ac9bd82b5751d43a38e4475d2310945a812262309094ae9cf59e0e9f3d02c92d8ab01f5733a20f051054a240bcbe3a7b6bb3f7c434229f631c4af239d33bd3ce30a372a480fdb49b2716091d26071aef372b8bd8ee8eb7f2965a372a836000b3737d2a833a39230e721e4844e16031ad69cd45ced60a64510c1248fd776611934d8d2a913d965e\nB = -3bb2cde9d3fda96fd7e6b24645f8e00b43affb223f2b5c3f4b7cfee905ddd6703a9d6c01f1f099ad1174da215a645ca4707d8156e762e2a253d7cfddd05ca19823ada9d33924013f677cfe4d86bde025391e0aaf91c6b776a9cf8a09dcad7cea59ee7aea1cf5f5bfe67c9d4456332d1f98e5310db9a0230381e1867a8f75b8757283f911f1a5e0d4afe5d544afa8d86637f9c9d87428fdcf8b4eb8f477e617960948253b24565b2f23081c47e211cd3c788a92732a49077f\nM = b18a9cd6a0a89578ea773f", - "bfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 30dc89bad4b449d1df9ea9b8f9d40b323c71d7e1133bc44d33bdb87c38cddedf83bb849e83436e4c92a06546fcf3e24ce6cc89d2e97a48aff2c7e3703da1b167a112f662a89742355e11e131e41052f1b379753cfa32cb0efa3a07465a258c585cd68c86bc9a473f5262c86c50992aeccbb9725b69ea8b3a7ebd2b6a24db52dc\nA = 60463fae1e9354559160d55a453c12d75775a53d1606d1fd16bef7e4ad1c78f9568954112f9280c46781180951534c5372dd5aaff3f33ac9c2e0ce4934d7009aad2ab5d6a5e5a141a36846e8925c7a28d116c68fb78aa9a687ec9bef173c1b69e0d7261f96eacacf237e1fe5874e5d553985b0fe7692ce8f2a5feab9ad9a2ad9c4bbf050b73b8030ebc36b94af8c6ecb67f8c94607d80cf600efd4ce4aa006f9b1832da8a1fdf8a564be0b4369149e8639e1714\nB = 15bfc50290b771ad147695a4c6701c47f2e8aec0657a4ef999eb45685200981b0ab5f8abc143d64878b85e9548651a1afd0913e3b14d11d3a26ab9793596801662a67b0062fdc8888feb029266f71d170518b6a4a040f59996bd4f257f221e830d0faaa9688aaa6afbc1f9b40d25097eab9d71d80aabc085f3a07e48bcfb37119aa00de60be55fd07d5b1281adf7b98bb589cdf2026252edf2f075ee176e23afa6b1f924c9fcf3c34c76752e833278a2e6b62017b88b77eece5\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8b506c9bfb75ab7ab420ae6c9b371ef035fab512188d9df76f0b31831573b44cb08266186a04d20cc761d61b6df3e33ecb86c269205c2c79ae6aa4d3ebacac8ec71d9bce1d7ab146530b131c9038041c6ce8152a6f1c09b9bec8eea4462dda0f08d75edf296eacbcefd62a0c197ed30f799343268bf6edfee4995958db7e0420\nA = 11c16713fbf8bc9696782cb5a88174cddbe68a04e8fe93dd074aab33dcd85f92baa178b2f3b8817be0cecb802cfd3ebb06734c9d399a1f090e3a8a2110aebbba0e920427bcda74bf11700b945985bd532286d44a1a615cf7c501412e454edd647f8371cb8149474557a0d47cbb782f460de7a3cc28991491ea0fc510286711b882987b09341c079565414f2c930e7c3c3a3e3e0f1d786260a7f45c70e0fa20dfc63849906af61707cfdf5a9b7a4291a1c1586d16b8\nB = -cf5638af39c6da3757a09a92e0bd54f852742682dc91c71dcdc6e72f7825a0979a1ead2e158479ce5565d22472dc3853e6bf7ba43296a5e0e0a355f0703cecc02ec79da83e3e9de10a6eccb858dedf7d4c400c27486a5b8cb34d787cde6a5fd271e83a6cf66057838fe30db1f30663cdfc22ef5d002b0b5a05831228ea200f95382a58d0d8aba36523d9b5cb7506f193131916f3ab66ac9552c26cd0c2ab1c449eaeb8fde752f4f3c3f9b060cc1f8a1e37c4fe5ec306674b66158\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 347706abeb168205cef9b0b8c6b9d6449ac501af7dfbdfbd41a20a6a47872cbd7d4cd32f7b0805ecf1573d534418b7cce98181e079d5061b02639fdf0161cea5314dbbb2ef39ec841f695281f3c7de45f33664e0dd1658f645adc1dd225f781a3fb1634517c556403587b2aecd56dceca9ec19b930cead2b1d303aa056d28bc7\nA = -5e1c869e5dbcc684c245d5c69093bfeaadf388cbf928d33a8ae2148a2b5145937e4f654c5f6a36de1124bad1de8bcc9067fe1f9a44fc6ffe55ce7ed5cd0dbb6337b0e1e96bac1eb2a3606dd97b0bdb975ea59448be50191cc7ea36481ca9fc85c1c3e1c97378dbcd6b355622046888df2ab3d18d805f4d31d464f62a8e630e955beeeb5e00c70242b8f8df708705abbeb95dea3561756298b5f3f7fe16e965294eeeea4546f5e8bacf9d6b4f2136d2e206a87dad1f47\nB = 70225f0cadd328be36ece2172c836405db3fe80ef99ec74fca25406b73a537adf5073f2b550abfc4c0fcc2c2850dace0da9a266768cb4d5ff7fc6c1c248ad74f47592101b61ef96c1302924381abbd96cf49f50c44bf7e0551721a8ae85abdf9925548d13b8c5d1a27be8a40d0f43eec3136bc3035057b75aea779b4262cc66e6bc68da93c218f1920979291105d4b02117d66deb92c3e511aa588b27130202acc9f69521957f79c7e731bbd5461552b9b6b24240dd71ac449be9777\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a2cb238f326d47f95869e2dcb295eba819a443dcc7c2785461389b58327742702f4c86e47af129f1fd4611cda93631f9333c358a29121d58286333083d13e66f30a9533b77ba3e26089e7eff7baf19bef8054af4e24735525908864ea9c4756b42a69c897003cab7b63cfd9a5927ed562e29845308eb2a55e7f8f03c87a5b7ce\nA = -1aa7ae6f56c38b654b281525b9da953ef366c2b9cffd3042105ed428dc7e5f2f2d53ef90b468bb471753606cc7a3775d86bcd2f4d5119cdde3c487cd39bf31752c5ba297e529c1b8121487e0e1de702156d0166ccaf51888a24fe7b48624eefaec855e2200929c21858676ec9bf4ceed0a832b69efd5065af544e49a3d209b85a77b0953652cbf0aa897527c52c9a98de9ae4c827f762e251478c88d410123625ea52b3478b52f6b9987d42009ae427763357ab53195772\nB = -226630b6fcdb5e274a25066ae2ca2c803549dbb935a97c0d7f6ab2c971d74cf6acd265c9d6815a6b2dd23dcb3c23b390fe8b1bed92b8c64c76c0ce62d5e7ddd7ce445bab0ca905dcfd0f128e5f4ffe966f3903d7ff1c61fe174e373cfe35a6d83249ec40b4a354d46fa1c90682efe468e895ea3da710838c262e8a47752dc6e7a79fe20051f51180173b58e0aa37b22eb8efee5b6dc264459ce4d135f430cb15afbf8c53f0de894bd2aca1f7ea32b4209a22a075f7b3b18e86f778a9e47\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9ea62ef634\nA = 55cc58c9d8\nB = 6b49179821\nM = f753311ac9\n\nModMul = e9ab3a2aa60edd30108\nA = 5134a36c2bad180dd5bf\nB = 2ba6485656d041690666\nM = 9b9cc4409e86c8b0fbbf\n\nModMul = 621f9b797e866028b7bd1ff828bf29\nA = a202338dffe171c99434d84f3\nB = fb71eee7045b3e3ab5dd809dd\nM = b3e6e8d53b7249df670e3c59c55d33\n\nModMul = 808d463d06b7b7f98e3cb2783e2196c349d62672\nA = c669426a92d3cb5b316e2b5b9\nB = ccaea3874008dcc92450d8b2f\nM = b04dd2bb325baed1940cd000e8cb2d786009ccd5\n\nModMul = 872164b92b9426b237858c4cdafe1694f96b0e0e4c19e894a0\nA = c3255cb24a813e27c3dc410f0\nB = b144f39e7c2d33605ba7bee16\nM = f3639f4dfb782f3107eb402fabb5fc878903acb5e02e129077\n\nModMul = 6124d7d171\nA = 235b938139\nB = 3a56a22a28\nM = 83eb4af4e5\n\nModMul = 9c006f56095d442ba98c\nA = 207e14237c42e3764e5e\nB = 8a495a26872432fa8e33\nM = d0cf2b8ae5c67d6736b9\n\nModMul = 97387cfaef652932a230c82de59cac\nA = 82ae0fc5e943af5bb8c4adebb\nB = db1279be12d59ba3a9c036a61\nM = aa36dc1d13390169cd54d711eb511b\n\nModMul = 32ee73c98da657464c6fed4274df20b099689e00\nA = 9baf08248ee24bcb17714e420\nB = a7f0428147bfe098666180749\nM = ce0bc198331c9ed1d21f0d498326e8185d3d602d\n\nModMul = a8b3fc0b53df3b92753edecd6fbcc5f4840dad3a44da704e34\nA = b36249e259b303e453757721c\nB = f0c1db50670d92abd93bdc84b\nM = b05cf978bf2dc7e093d7d164e46d547219c480382df32b33d9\n\nModMul = 2663b741ff\nA = 58c8e7f7f6\nB = c84681fc87\nM = e0a50dcb45\n\nModMul = 21af3c0b42328f41b81e\nA = 1f79f5b5bf78c9700d\nB = 5bd1734ba0f0e59c2a25\nM = 9ff3fdfb5c089244f327\n\nModMul = cbc280b5106c2c36cb31ad7e7c986c\nA = cadf6482b769e83ce7f7277dd\nB = f9862a06da1a9c89547b76c61\nM = cc36144c88139ce921d2fd1740bc4b\n\nModMul = 3813f2fabe016e19fd8e70687ff473651a5fbb4b\nA = 9c51a5bacb5d9f055a9ac2962\nB = bfed5625b21b4e82d1f105a0b\nM = a47977acad7c5deeb683ccd265cb30cb193f22a9\n\nModMul = 76ff291a02715fc87ebfb3e99153c04e53358dbd7beae43478\nA = 997c4a7b537d9500d73a205a4\nB = c679ce666af284a459ae5a26e\nM = d0d0fd4922953941acad8beb65c00603b19eb44fb8ca51e3c9\n\nModMul = 1a90c92fdb\nA = 94fa7bb475\nB = 564b0a3339\nM = a1501bdc75\n\nModMul = 5e7ae5470686bad7996a\nA = c725797912c6c5f30d94\nB = 3a7f4c99ee3f5fa9582c\nM = cc50c8b7408f09a74973\n\nModMul = 72a15b13bcd1b63747342a6be8f0f2\nA = c33357af48a2df569e3c11ce6\nB = a4b4c5c14d7796adab54b6cae\nM = e22a0fdca62a37f4c8a61c96a429b9\n\nModMul = 31e179bfbf65b0695dde36a4fb72d131830dcdd6\nA = ce8d3adab8cbf15c332c0b289\nB = 9333f94eeb7d7a86b82becc51\nM = a532a76bd5cff409b580d54d12ef75ad8179b381\n\nModMul = 8f4b8a585415adff3a7bc35fa88891ba31e4a82672c664fb14\nA = 9a2b56a54bd0727ab4be57ff2\nB = edf1781b4296567990773005a\nM = c5a7c3b97ba00d6f174a019c6d37eda52036c528f351bef0f1\n\nModMul = 917bcdb402\nA = 55c7dbd314\nB = 997b29ef79\nM = af5b4cbd0f\n\nModMul = 660c4bb2b771f523a4fd\nA = 43fe52461d5139620a11\nB = 1f8ec4b67de1db54ddda\nM = d0458e215b7e6903d96f\n\nModMul = 7aeff02c143e4426fcbcf32bd1277b\nA = a2671586369a990dde7829f36\nB = c7ff67937c900daccc0ab1d8c\nM = 8ad9c1d4d3cce681", - "d1ae27c27982df\n\nModMul = 4b153d57433f0f7276674d3484e9bd0d25227d07\nA = aea36cf51dd2ce06c66b7a407\nB = 80c9fe5bb0afd2bf8b3644f96\nM = 8cc22a67ed7e5a7a2322aaa09ec2be94998494f9\n\nModMul = 7f8447dd983b113f04c6288f9539e53a2e9cddbca8b2fefcc0\nA = f67636b03821c8f13f21217a5\nB = 8473a29f4ae33f36a0d2c6dc0\nM = b829af37b557c3ddbb5257c8b19144b90708a45a274d6655f5\n\nModMul = 17fe4644a2\nA = 912611576f\nB = 7a10d36b80\nM = c5fa605133\n\nModMul = 8159b23d4fd697b4fd35\nA = be2d646e76494439e60\nB = 60fa770d05ebc69772b2\nM = a6e7c940cd749925a85b\n\nModMul = 7c412dad5c9fff91357bf181caf2bf\nA = 80f476ed5acae75b34ed54c52\nB = fb818e2bdab3b5f4bd84db3d0\nM = d0339f7ee41337d8462d1a9c207d1d\n\nModMul = 70432c749da4ade2c38237545ebfe6c4c6a92f6b\nA = ee9c92de52210e61adaa6eb4a\nB = 8ab55a85b1abab62d33e75fe3\nM = cd3faa6de4cb62fece4c3f94492d457834a6a041\n\nModMul = 9fef1c18778a8691c5e71c0b5208e82778e9bfb632da0b7e28\nA = bd162c90bed25e84dd5b6b77c\nB = d887ee03020c5df356f091db6\nM = a2c2d45fe9decd93a0ca3edab8fee46d27ba23fad9b5294d5f\n\nModMul = 958951bd0f\nA = 12bd0d3375\nB = 668bb65b4e\nM = 9c617dfaad\n\nModMul = 8a109ebc9cbf86613e43\nA = a3e7019f1bbc35689a77\nB = 3189ecd3fd4ffd0229ef\nM = ddadc50600dff2abc1af\n\nModMul = 2b4d9f85a398c852b3a0cc82524619\nA = c244fd157267f707319ba6c6d\nB = 8a07018a748992429bbdbf326\nM = bf3813fb54f749ea5627f59ce30e07\n\nModMul = 28cab7d574e6dc56a6a622f8a7523cbb8dcc5e0f\nA = c9909dcfd3a59a3cfa538b267\nB = 8bbf89cd5a4e24adc2d8c646b\nM = c8f02682b9d480ea98faaca53b747ced33ed0419\n\nModMul = 69b2dfb3f1d8dbb13e9e479f38edcc427d5968acb7751a226a\nA = 8019266c548982a520ab48eff\nB = d33c3e3b13576dcdb3ffaa796\nM = e6255103732475604df7c6f7ef7e6b49a8ef9e2b0c717925a1\n\nModMul = 3eaa4c99fd\nA = 6fc42faa85\nB = dd0b4e318e\nM = fd7f22301b\n\nModMul = 56b6b811ced3433755cb\nA = 145573d17cb0c996c69\nB = 9d3297d5ccc184896822\nM = dcfb3b383506239e83e1\n\nModMul = 34315b6bc6d3690c28060485ae331f\nA = b963a26973894cfb42fcb2d22\nB = e8523304bbcdff1a0ed4141bb\nM = d7a379aeac7d8cf94f19e7924d35d1\n\nModMul = 2ec9466e8b3357496f07e37ba24d36a237883846\nA = a75f3904e564997695b6707eb\nB = f9f47bd779834dc1f5fba0654\nM = b3ae5abed45d09c4dc5abcadc3ac9abebe1949ed\n\nModMul = 88b4d86b2c1e1bd780e8d2499c2221e05fab4f9b7047c2a044\nA = a38eceb9c551f0e69a544072c\nB = d5f8e7c2d534b2b8985bfd213\nM = ff81809b84fb8eed3508ad891d3d8208249d8a902a12d6acf7\n\nModMul = 172f2e2e22\nA = 1584ff1055\nB = 2e0aee014d\nM = b904cb0bc9\n\nModMul = 122c10d3200270b9eaa1\nA = 86fd189e62a6dc1e4ba0\nB = 5235635f7b0336f5f235\nM = c93da97d0e95fb63dc4d\n\nModMul = 3e461e10ac4eb749512097fbf76616\nA = cf4ce10cbca07164f3812f89c\nB = b7e4639c233fbb0f923fb5104\nM = 949647857e1406871593fad5c30101\n\nModMul = 88117b59d9fed79dd6aaf083ee938215a995a221\nA = 94c888795567d434123d441a7\nB = c60ca79e61a352e34e0f78bee\nM = d2553a7c5dccd639a3927697a2e1af03845f2f25\n\nModMul = bc5f0076a8c2f6cc8f4e61540d2d6f6d6b13b775b363dcd71c\nA = c170eaddca5295d6ec6272dc2\nB = f94a5685ced7661df2efbd34e\nM = fa6bc46aa05033af72aa42793e9174af2e3ba38992f33572fd\n\nModMul = 1110cdbe5b\nA = 5db02b38f3\nB = 3369537903\nM = a8863f7979\n\nModMul = 90fcc5f3a346d3d4ea4c\nA = b93373680ea0feeb31d8\nB = 37f9dfaf0e180be64bd5\nM = d595cc29237d1c19e2db\n\nModMul = 8623a9997e514cf3c1d06c33c14053\nA = b396f5ede6212f1fdfc7e7b77\nB = 81a1ddc18306f2d2e84030148\nM = a6be32a91b34857842255ef8b1aafd\n\nModMul = 63f8f0254df06356f5cab8941b77619ad58025ed\nA = 806b2627b08d987438f920bae\nB = 83297039f4aa8efc1a185fea3\nM = bb8a7e7c19be02c25cf5682a0eee655fcd5b69a5\n\nModMul = 697238dbe3d395e81f20c9fcc8db30c234a1f75f3b2bc27438\nA = 930b04224bc097ac1d8bae8be\nB = b79496a80e45212c4663e5b64\nM = 8ff7e19d967d317c255380411898d73e3786269f09079f19f1\n\nModMul = cd93b5b8b1\nA = 47a51b2d5a\nB = 86d6ba5155\nM = efb0ad3643\n\nModMul = 2037821ea789118bde0a\nA = a92215dcae19be637ff\nB = 93b9a3664a406737958f\nM = 9df360b69ed26f610253\n\nModMul = 3bf11785d28ceb668dc55b870faf7b\nA = bc8758854dc48e057cb6210de\nB = f03ca689620a77ecd8a6f0de3\nM = f3ff0747d6e5f34a0ba4200f579259\n\nModMul = 7b30b44f75ed12f54136858ce4fe77d00e0952cf\nA = 993cd09f3e46423a8ba2053df\nB = feabee384158032dd013dc08d\nM = cd0b21388cb2033b1e792ec4078334df70b6c8f9\n\nModMul = 8ce1e17972f1a9d2e9437d0c5219354728a5f31337808d7650\nA = 90e5d18b017118177ffb080da\nB = f8e7e09032574f6c66e623ec8\nM = da795e6ef63ff7dc4baef5c327022ccf65d44e3c4e24823f11\n\nModMul = 8fcd412054\nA = 2e7f9b1a\nB = 6283de2c9a\nM = 9bff560ae7\n\nModMul = 57d0d3b79f1e2f3632fc\nA = 2f8cc403de5af54cfa39\nB = 3b798c3ead52878dfb2f\nM = 805e6cbde400d4b4bc9b\n\nModMul = 23331614e88633af879201f568c359\nA = f21f19da4b20980979a645dac\nB = ea752050b79883dcd69222536\nM = aed3faf4c88f7c4afe257c5ed90599\n\nModMul = 56dcf9ae1c787e773774df3c8762babb4675a212\nA = 9accf901fa599da05fa6ab5ff\nB = f7f6b9b1d7bae06237532e39f\nM = b5bcd776bb2eb0805ade3c8b47e883962d3cbdf5\n\nModMul = 61d0ee0786963906a028a1df01f836841ab6d39d88ca2717c0\nA = 8e57680f213d088ff1a1e7db3\nB = afebecc9943b0093f87022940\nM = b6201f68a45265d7e9183c3255feb4c110c05dadbcb13881bb\n\nModMul = 143ae78a29\nA = 334abb952a\nB = 74203e7a50\nM = c9535a9505\n\nModMul = 897a2b57e69f5a1469ea\nA = 1ec8ca0ea4fed52bdbbf\nB = 3a6273cab05e478a57b8\nM = dcb33163a8ea42c1ae6d\n\nModMul = 4a2c10e90e2d37111db79a44d3e31b\nA = a90e7bbd63fc4af6de83029ee\nB = cf09c3dd50b41afc7045e057b\nM = 8ab85d47e4270116a64f97dc4f0f15\n\nModMul = 70f94276c9d85fd3f71edfaad6051456f754da85\nA = fa3e9ff6e1aa1fb78e51711cb\nB = b115ed197c50b7ec4040ca255\nM = ad63f69ef1346e7549ba71c13b24b279f53bc9bd\n\nModMul = 861e7ef401866f815b983ba18a612913ecc20a67016d79cfac\nA = fc41a9ce06e882942f751be7a\nB = 881c05a51d1ba8134d126a48e\nM = b12200b39526c33b70e8aa23ebc400dea0d4d8fe42be103d5f\n\nModMul = 4e0051898a\nA = 2a06523f70\nB = 651b5044f0\nM = 9da4eb09b5\n\nModMul = cc8274c88d6affc3742f\nA = 9ccf0133f9628532f4f6\nB = c1d80907057be7a67b01\nM = d6e76e362da831f32685\n\nModMul = 568f15bed5c4405be9dd04673a9c46\nA = dd6029c3196feb6da7f0f4a48\nB = a5f6745f2cb64913d1d3236d8\nM = f62f02c9b9ca8993e3be9a02b444bf\n\nModMul = a629452d5ed19df040eca26eaca37d82c0fb1d8f\nA = 963c51a9415b03e85ccb09f25\nB = b1cffe333afe44311cb968ffe\nM = ab2128698d498e8d75455033cfbbf4487535773f\n\nModMul = 814030123025d287aaa8b826792999d72f2d589e0c7f7f3dbf\nA = c3b33f391e78bee97ceddf313\nB = a9136f3af450fdeb245eff425\nM = b6aa9c517eaecb70781e597b907583bbb569e970d229235a35\n\nModMul = 8735bd486d\nA = 563e15c52a\nB = 31293264e1\nM = 92f4b193df\n\nModMul = a541f69ca163b288dd0e\nA = a608b48c1dcaa18424b2\nB = 891b0b296e911068b00c\nM = d4140921f4b2c84f1eb1\n\nModMul = adc1b7cf65967b013d046866b4ed9d\nA = e97941448f65060cf63ecd486\nB = ca68936f76cb87a8fbdd37311\nM = ebbca2482fb82eeca2866057cf1179\n\nModMul = 44aa9f0dd58d4510a7364e130698b34eda23a632\nA = c11f83f01bb964ffac93a2e30\nB = e05ee40eea39f4538d735193d\nM = b5e8b511738979dc740a6a1f7291cf4561787be7\n\nModMul = 8b16b82f064f471983c7154abc9f9ba355111bacb90400372a\nA = acff8da571e1c96810bf95707\nB = cdd23e5504cc26d0c34a62b06\nM = f38902a99190ae0b5ef26849a6e943d651925666fea271fee7\n\nModMul = 193f453197\nA = 8cb3078675\nB = a8fb003a87\nM = b60ff22f4b\n\nModMul = 849c26c8cf5cae426a80\nA = 5d1e3d2b4d038a0a34be\nB = 34f70325565bf0523314\nM = cbc189f9a732cad8f425\n\nModMul = 9a4e64ff530c53a4c6c5b6b5021920\nA = f53b81723cf74f520a61e614e\nB = 9d8ac2e6b839143fdd079a2ff\nM = a115375435151798f3644bede9d863\n\nModMul = aac303a4623e80158af1cb3331965cc8e3184edd\nA = cce0a88606ff962fdc37e72c9\nB = 9840a500a2051625c517104db\nM = b99dafdbd91ec3c05791031df5e193c03d6a441d\n\nModMul = a31401dfa761bbe82b66b5f094151865b18a4ba75bb9b3dedf\nA = e6f48c027284856aaf3b96425\nB = b4c326f72a6a22fd4b93ba5b3\nM = e57d9608ac6e5b129b2c014958bfc59137f63838b1ba88a4ab\n\nModMul = 8b0929adbf\nA = 61fdf77ac0\nB = 8892f05400\nM = f12b3766eb\n\nModMul = 91b57f353307b173679d\nA = 33f8e73752072b4b5cfa\nB = b4c730f79f4f2c07945d\nM = d41be1d8d2e5753e3ae9\n\nModMul = af04c564adfeb120bc4770bc8c650c\nA = af151333b3d4cd1d29fd801db\nB = 9ccaac44ff91be11b30bdcdd0\nM = e0bd6e70d5f5ce08fbbfd48d43101f\n\nModMul = 1b8d623796a5065d9e993a53a9587a0fdbea1bbd\nA = a2fd08df2d4eab0cd6d29e213\nB = 92c9d26ae7c215b52199ee28b\nM = cd529f4cfa46f3bd3e7fadf167fdc02f6f881da3\n\nModMul = 4a8573dd8dc50a4fa39f3579d3869745eb8c1153ca508deefd\nA = 855f941d085305725da617f5d\nB = 8f09b7d2c36e0340523da5421\nM = fd8caa05edeaa81beefa01957eed97a981ab34bdeb6d8c704b\n\nModMul = 2d278e089\nA = 59d20a1716\nB = 8e2a58bc75\nM = b3d61ef699\n\nModMul = 2f937ce359d0f6cedd1\nA = 1019d11d26040ffd5b1d\nB = 7cdb6252087423d43e08\nM = e8f537323004447e669f\n", - "\nModMul = 6567332e25af83089f7458786ab0ca\nA = bf9565e9f8a098894447b58fb\nB = fc867626f268c24cc0ab7bf8b\nM = 930f39183353363dcd822933a438ef\n\nModMul = 3692e73ad1d91ddc19cad3808eba2c5fc88e2bf9\nA = d0a42ce512629f0ffd233a9aa\nB = 97f6d3c4c655c7353a62d6ac4\nM = eac2ea84851f880214b8f40f881a2e56a6ba6f2d\n\nModMul = 81df390c9e51b30bd639db15adb464c7cb1d011cb5e260be58\nA = c237eb242c40960861c938c08\nB = ab2f481f0d768eebd90d2574b\nM = 8697d7a28a5f42c9a7b31949b8b568f861142f44fe66c6cd3f\n\nModMul = c952f9aef\nA = 81973bbcb3\nB = 28ddee3bf7\nM = c4a40993c9\n\nModMul = 241dd53d93f7bdbbb2ee\nA = 2136eda4495c45c9f96c\nB = e74c4baa8ca3f6b7cd5b\nM = fff4594e7a5f0a1d3e15\n\nModMul = 5f861ed8b0aa835761613e6c869cfd\nA = bfc5c1572086079f5f5d18d1b\nB = 95902e14923c8010b7e905178\nM = a819c6c109d623f9b845aa23712c9b\n\nModMul = 5b8ab089c4e4c6804e48a2bc1d218718b3a32598\nA = fbe65d3852224a812c432672a\nB = d57a3f38da966d2471d70a048\nM = b9e6a626d3ad026d14248fc90c882bedd64a1f13\n\nModMul = 761438baf5b02dc095b7040e082da7b167c2b9ace956284ed\nA = fd91701ed2151f8e994bf4ee1\nB = 88b66e735b76972bccd9db182\nM = 8008b2d1274456aa68dc627b1ec3e1762c6ed2d660c64a1a55\n\nModMul = cb743c97a1\nA = 9c69ca9b60\nB = 7488f48f5\nM = d67040ed0d\n\nModMul = 931b2bee1bc30725a31\nA = 650f567b544ce02303d4\nB = 5858da30dd1fae88a675\nM = 91ce30234bb29fb9e833\n\nModMul = 5b4f262cec958a20390b5e568ccdaf\nA = f7e240e8a077e8e87506db2f1\nB = f8653fe64e3bd414782f51634\nM = fdb8225eefc1620648737d31dfe1f7\n\nModMul = 4c011d1ddfa30c901793cc6ce74db47584cebbd1\nA = eda8e9a9ea3cdae17bd50b1b4\nB = 992e8ef4a45593e4ceff67876\nM = 95e2f120cfcefbada1058af6c8853cbebedd5763\n\nModMul = 6e99aa5b8107399848cf24fbd88ed6350efb68d737e505b466\nA = ca6c51ba2f410d09bf71d60fe\nB = 8bdfa8fe5ef3b2ad02bc63c4d\nM = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb\n\nModMul = 536175913582e73c1002083cb0cfce5471d4193a5b717881e60abfe927c829d\nA = 9b474b6f7d7f11dfbeb7a0724694f2daf9ccbaf2ec13269b5ae3329e8df95f7833baa68324509dcddfb5afa1d14f2dafc55e2c225475f16fb396beecc7a66dee\nB = d74a5081f00af2361c3537642c06cd47aae7e366741c9b4785e185af8b328acf3e2ed71e3b9a4b6fd49d956eef76740b3c6ec5850a90e7e444dfeaa7214c5eca\nM = 5efaeebe212752b28b5441a5d0b2600190504467c6359e9ab26320ee72cffcb\n\nModMul = 6161cceee2b74e7965a926fdf5344ddf8cc41994d72154a8b6014c18cf71634\nA = e7d6b74a1af0834aaf93e09a6488340b661449ba2bbc73d775e7d828163813ddbcd82719351879a6d67ab6b518011e1db43a3d620d1f24403917691d15ed6f90\nB = 3ecc8fd3103fe52a7e73ec4be4e60b69584bd886a030f017b482bde9d4b0b964ba8471cb32b3e9bd49864d9028a22d6b6b46be0451bb4222c3987b74a509f8fc\nM = 7c3e3b8b1a6110da82674aaf88c288cef4cfddf22e7c9b75640fd67fa5fad59\n\nModMul = 2acd55bdcccd55882eff0bb262bb62f78bff8e932aefc9d32f54d5d4e9b8bd76\nA = c221d1f0d1b7efe7e078dd01bed773f8876fa324b3fe91985d47d343e7f3878b457dae2f9ae68971245278a1d23cb541c56b94dd9ac43a9fbe28a46efc627651\nB = 49f94c19ff7ce990637c3d2019ed66f7e6dbb1442b04a4593cc480521b991cb1b878f8c31903240f89e34336d9e6785433617e729b71adcbef622a683357e035\nM = 43760c71742e9cf22cae6fc262c008b7f1b97a78c8063957b74aa4cd370c1eeb\n\nModMul = 504c11e38284a30e3647c1ddfaed94503d833bcecdff05e749422ad1d9442540\nA = 3fbabe2d65f443e7db0a6f332330ecc4d1d40e14fcb510499552020405cafcf10a50a5ee47cf60fd8c22a22b3f753b4167c213851f32109babe4b5c298d6c4cf\nB = 62e5b0f887dcb1f1794bae7dad46a066f810cf5f82a1eea99207b5f0fb0ae9084c5e62cc97b2672b1cf4cc1400a19bdcb093c97404876b584a6482931e7ba9b7\nM = d79fab3eb31189268b2a0689cafdaa0826f07d432591e8aa8bd3c7cdce1470a7\n\nModMul = 13a6431c57ddf0ed3979412ba8454a0dd9a2694a0dd76453aae63366c46e41db\nA = 7e1fd0bd9ab0aa75b264475604aea09f24239f94847ce2549d43b71890c0549938d167adebc7890d3c492b5874da7bf18d895ccaf1803b9776820598928b407c\nB = 5e54e5185bc86f16177f1354a57d36ac2980def141b389e4bfda134fae7c158009ccc61ef66281905128b6297f876662104ead2315024f129c56eaa387f80b4d\nM = 182572149b860615dd853f37f7d51a35e85f5e4a4249a60fde58dc68e0dd7401\n\nModMul = 145a44566bd75103083b7556a822ea6008ed3a6a1bf135b68fcf87a294c09b4\nA = a195e4315caa8cc0707063c7359c28139d4dfffb57eb726156336e13227ad9766ea1fc99152893ebb194fecfc153d47cb927a633217328f05e4d8782aeb89d04\nB = a97ae97dc7e9a224cab94ecedc08d0cbf7a012dc5209b1e1e8b5b843fcf61e65db3457d6085545a633be47b742e8237cc716357ff5bce9b00e23671ec1d049a8\nM = 29b060ee2aef7e43e02163d279ce49259127198adf462d13aa195c7dccf573a1\n\nModMul = b00740cef7791692d45f5a7110f3eeb260638f19f87c9245436fc0422de90658\nA = e6b97c11ad44fd451d168d65d1691d2220db8c3b6c8436d59f4c1366aac52558d0d6b61f5d6966460a4a31085fac711e5a09af5563d938963555d4730982eb0\nB = 6805eab5a4da534f07def6d2c320a6cbdfe4831fc2163dfcef740607b3181d8647bfae8f8c16237c1c1c5d14b9e3417132f81b3a7db4b7fc11927aab30dca590\nM = f975a94fa62b4c0e68df5c3ac5917d18927c0a6d9cf39c26f6ed97a81cedf227\n\nModMul = dc04b6ba2eb1e34ea8942a50d1d0c5479dd22109895796ffdc9cd32b53d4764\nA = 7fd3310af09a67e0684dcd8e3b4b651c7c13c2f6a0a47b59a7f5cd8bd80854d1d4fe02eaa61843d6bb2b87f99d8ec4842864681eaf056538ffff610c231e1d\nB = 15f1661c59ee9f93400073e18a91503a93d47537d2da5cf5e4bc69ccc87b07bed171a95f1c5eaa9c7d7ab207ab3f1f7634c5d16e706969e869364207f61d84bf\nM = 22e2856f4c2b6c01448d4aef74aaaee3a14e9660b5b277200f2e67464ecadfab\n\nModMul = 19299c9e960ce15087e9fbd66f95cafe82546431b92d70db1de87c3425c1bef2\nA = 8e3abb1f24e1f91496db99be9409f57f67cfb6e0e33d603a2a31e1309f1d0bbdc413c3e4fbb5e3d923f683afa9942b9b9fad6a6e558b2297889fff47ccef7d23\nB = dbdf5940dcd68127d476badbd5a2f3018aa4d8db79f81337ddfcb108637110b934e946d3284ec09d5255605ad72424f1894238ee4f7964dffc27fad838532321\nM = ab6b4e3d3909512f5d1d62a30c1ab8dd5e584cadbce9dffd12fe203f8936ee93\n\nModMul = 4f88ad4e30e6e8e38cba0452d98d4a3547c680f16308692e33e5577772658764\nA = 5137697bf48982edd869e4a42f3cb858bf65ad5b25d1c0e8b75d054460d0944ecb5a6924721c5728964d84231c7ae808f556837aefb23fe3ad36aec9f5f60f20\nB = c79554304620f8116b9a8bb56f6a23620e9fd504f7163f732e1e6367d25c6ff98cb01d16faf3e018dec6a067d1204a6aa95470598ce757bcfbc3ab4f5d8ec88\nM = 9ba20dd78923d8ef82897ac46a509cf22c9b7986a4facf42e5416bfe3576a735\n\nModMul = 985a4d2a7431e09fcad03e6a3f926582dbc0aedc588f17aa5db40c2d3566233\nA = 908bff40440aaeee6c90b6312dc017c3bdae884a9074e02b26f01be1f018390e01f0d111f99a06c16e20538df8000d4066cd4bb3628da88a3a5cc240cfac719f\nB = 6ebfe9fe53909876784f9d6e5dcca4cfa9463fbd8426c5bb8890ae84c2fad119615fe1e1f2ee5fa544a5ac713ed1da8c1e04f282f1f1b9fba4b4c4bd9db20538\nM = c66842e0a11ed6ad1e8f192ea97f5f244536cfc5234c7fdae1ff905123c72793\n\nModMul = 133d7b31537b627da2c042217cd28625437c28c3e06258427d9a4384046a1f4\nA = afb695e3e40347f60a500e01fba4df1c1f2fd4ed79e3f65913d82369f79d80db6b3978e6351c70c148f572b9c0c2b1efeefa605251b3156d9b66d240467e550f\nB = 8855046dcf50f80f278227d5260b9be53ca2e4a1cfe1afce4d35b11d0fa17a36a8bee8126e13bbb318d476becad5a935e9d160fa481e1437b292bdc169dc7d45\nM = 3eae4f0d6c7e1fb9de1a4c160404a8767783c7f839fe27a543f5c389c679d47\n\nModMul = 7f4576a315bad5c7fbb1616e8b26c5b34ca6f701b9b1adf0485fec181c41dee9\nA = bc2baf0153a4598f6b5f488c43b2546cadfaca2c1931b919f98ba71835a8fe78886da1fea25b194e60ed6f9e0ad23c988b64af9278155c1722dcf4983a1566c2\nB = d8374d91fd3c523ecdd6bdd265c9a8958dd222f9f0e25454fd683bd86d7900a273b56f1f47e033c46527e32c721094ce6bc927d25fac05d7fa6db4d7a6773c94\nM = 9975d8e7f2a4d9d1ff8d442b93ff269a83fee43a18bbfa8c2ccd7ca5fac3a8d3\n\nModMul = 57ebfb39605d4fa6ef5fd03bd8e4fd685664297c29b7ad75a40b133e15fc5ae9\nA = efed8e442154b1eb6c75775cc23e01fa65c9c361e222da123d07daad3039f305e7102edff23b65c333f0caae4f7929857c3169f4ae47c9f0fd920c38eb42bf2f\nB = db05415ea90269a74b0919ff772c148c0eeb2ff9dea76a6e73e82eb86bc76fb42308b55ef83a769a91d23b7840d5d2f5129f15279dfab7cd8d63778acf202f26\nM = 7704390c4b1da86d51ff817003e5451d601a5352296e339e5da219ec5a330479\n\nModMul = 40b6b0d44cf8a5ca7f4fd03dd6e1e2a11f74f3911dcd8727e57db8d65cd490d\nA = 6500f3cf686eec4e1f243616ac0ea8e8d11ddbade490b86baf231e7b2fd55968ee14b6bb7badf8c898874099831976af46bcbfbfaea10d49aa803c6e51238e2\nB = 1fac744fa1e26e789639e049679d0e2eb57336279f09555e10210e7143199a3df5fbf5294edc386ac762fa3a3b0b4bc28945adf21a8af747a29018bf76d3710a\nM = 5c0781a87b84ecb4362b09c623d511de53c085671dd4f08e9a551685b55ddfd1\n\nModMul = 6b778ae9822221e6a8376379e0032d7edb14d7b5e32a7310897b54d1d5626113\nA = c4a5737a9496129a136753f8c2e52bbd2660f2d3fafe4ed702900b01c14e506d13e3bbeab19b357e5ba9fce8a4fc3dcc469406a16248d6fb53862781fd9d55e4\nB = 444e5a673eeb37fd3b4f6b6f5133b0f46c2ea532e1953da4a0e144407a8e2534c5ff40cc9af7756e5aff9df57d938fcedaffb", - "868dcf4e458b36f506ed7fe0ce5\nM = 7f5978c0c066132a9bdcb00727bb802b72777b9e8e4265f76b80cfdc3a788817\n\nModMul = 5c717e5dd25abe60f761d6f9326ed056416add4c1384682d87b7ff12e112f855\nA = 4351965a421c75c5b4c251861e53316a300ed7983e27e17f9308420f0d2cb11e9c476294fcd9042a525bc1a044bb442d1d9f853c9e07245170e0e2711010cd1c\nB = 4e1046647c362c8f9c414be54075b4e9d151c6fa0c3da40d90e6042625947ca2c9f20cfbcfdab8666dac5a15f6cda9d47b09f654131fc5addc07e382c9639323\nM = a6c789884c66c7f028099e0367b3ed86871277bf070c541ee12fc02fcb6181d7\n\nModMul = 4452688244f542125168853f1d444f96ab0f82903bb12a97e59f0db633edfd6\nA = 9fd1cc81981bff977244c044146918057ad06d3cc26edfb8fb4118ee02b959d45555f9507ffeb23c3688e29ccdfe5f583fa3761f6727573542bee8ab5f5b600d\nB = 856e6a03b5c93fc19deea51b3bfe42c810c5bcf9ffbd08e2625eb209baf6a4e24943a3c090d89c1f70aea9f0128e511fe92e03715d917168c1e1ca77a3a8731f\nM = 2c245d407a78903ef2b279ddbe32106e6333b6f44cabf87b8641b047c79ea06b\n\nModMul = 375f8474ee47df6b9a038512002e56cddd374d69c69719d8d369232c64a839e2\nA = add40f1dd6d4a2414b17f0c628eed9a8f082f3ad1f34ec41935fa86b34d4505b22ea80c062386a9ed63f95c67e55c686f837bddf8f4da791f98b08c02f32d4b2\nB = dab1caaa11d5a208b7a6b7a1d6482a4859daaba5e3a77b1b1020e8ae62a664953dfddd0b47d40526e7a3c6a5363c6d41dd9f529fd8b58d5d31bb67e745cb71b3\nM = 4f506313a4f49873a405f2e5a6e9cfae9cd5e9f67b5ef900153366570e28a955\n\nModMul = 36fb0733a26902f0f8f11625305a3c94fcdfffe294eb6ccba110aa628a314df\nA = 52ee1498bd6a1677db801ae2eab4951345a1fcf8fe7d38e3f28dbc27fae508d87c9958e02a375ff4891b88ee916b96331e7cc082615faa028f6d541b5ce37876\nB = 9343cfa074f50c20e8472f8f7c4a7d330aa30ee417ed8027a4c956e84cc5cb31d5411c14796d9325fceef79a51b5d8a4c89182ca273ab633e6a7b22a27352300\nM = 9d7c334aa33634f9f313b71b42476a3b627a6c5bb8ac1d07a8d732d5c087bd9\n\nModMul = 4a377267508eb045e00cea66a417112dac07545304bbeac6315625275b7cbfad\nA = 19616a82b75b08499d4b1f869df2db8f71398672f3f97ffc6177a4a5aa913605ce8a6ab5f778cac508f0b3f2aa680b01ccdc57c0fdd6cd678a2ff2dcd7f01f3c\nB = a5643a9a9fe3be4134082daae4ee7dfd85d9452beee856fd939d3be9788b6bebcf3571c67ec481ff9b20f70d23e82e2171b1d0ddf0a9435b40115d32aedb6811\nM = ea0477e7f1a02cb6c21171066f3dab69d4e24429043b0f049de660fc80e51937\n\nModMul = 7952dfdb91252658430e365adeefd9093740de92cfc9dd3d92294f2dab6ca0b6\nA = 8e6cd7639b7c134b53e6ae6ac5f51268da83ed09e8e96d65e4bb130dcdbbab9e48226ddba6efe93faa510bde8ee92f2a641774c4272b5a2f88024b77a2cfa110\nB = fe4e8109a49b16b96871e384564cc096277dad4e1bbca8e5feb33f140a4fb800c8f3096b1bc7042bccf249aede88e6055c0db609f94e214b1251eda494be724b\nM = aa46853682af960824140c35d145a6dcff6283b2c59994b30ecf9b8def41a025\n\nModMul = 1aacec7f7e66b0cf4eb2dfda9d8d3fbf4eb8e928cbbc967d13e3e38612f0346d\nA = b0fd7a936b0908ba6fa797e4b855d673ff85d665ef3a345e560e2c0049becf5c25b6c0068dd617ab47a8fd151939ea0631f86806ddd40e557933c0e880fcdd0b\nB = 105c87fe2b1bf0be5405ca0d530beda1780f0045e892d7810f8a8abbe890f0a19de66497cba55bf38e190c52992467c22a320c38a4bd167f774ed812f1271d5a\nM = ac4f0a2b22df691331ded955a5d0e7d1910d7920a59d4a87636b2635397b7335\n\nModMul = 2c25d180156fa7d2fc20c9bd6d9ff0b111c9ad76ada0784e2f8fa0bd06413f66\nA = 2aa4a0a73df11f4e60956619d0b35eaef45730d619f9b920298e6d369b9861f6411de28a34af038f288d7a3d6a35b10c8082b8ad0fb275a8f67c6832ac46ba9\nB = fae1d50b72feb25da2581829409391bf289cd9f730c99d265b5b2d63889381cde4adbf85c3998c2478f2866526b8f64605d75765edd09b78ea45337207d173\nM = 65c9d79a09a820adbc9beb152bef387c1439147ed50cef872d36a69f1c7d5fe1\n\nModMul = 56ec8624fc199e7b4e68358f88f1a99f1d4d02577b8c6f7e28e4ccfdd981f995\nA = b0a0f9d05d144d2ef257c1e63a7127a3b8e0d8b64ff8f6447618560593574b5c5da6258b274efc28da0defd988bef1efca0f481f809665a78954b36741d668bd\nB = 10901b9dbf0016cbcc671da75a75b7a6ec6a66dd17b53a97344864b08f037098537380bfb0137b6becfc36a75206686d16bc4eb8fd54299494374e3f383d9b10\nM = 73882376ca850c125ce9f20c291e550ee48f0eb0d571109ab08c22d6719496e9\n\nModMul = acceebe131aa34ff21b3235f045bccc8a8f762dca20c1dd1ef6eb461ea971c6c\nA = a7714b249eb0f0cbe3e6fa0b04e895fcf14c404876197defafc6b57026ae7e5e993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b\nB = b7278ecd154ef5243ad973ead291ea186acb63e09977e644a6a9fde195d1a33993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b\nM = c52ae49e1a4b21ec392b76844ad559653b7b9f67a58b3bba6c2ce250017eab09\n\nModMul = 62b5b04dc84bb4ee04934c03ef361bc6e59b42144dc117b9f7771525c67c3688\nA = 2b65f491caf0b5cd9c66c859fbcadaec7213e6b848884638791b1620d6e4bc9dde087af0e7329d3b15a45df2d43ebde61b053ad7f63917aa922d58b4f3222620\nB = c1bfcdb34b0766be980540dc3256b9ee4158310fad2c43cf24bfafca08ee185647043f5842a9d9eda224449259341b7c50998086434528d47661bf5762a7ab5f\nM = f73398c32191b436d14a0b76c6069b1d61395568753c832dd0c707780a232dc9\n\nModMul = 5613c8fb0721bd3f605089def48fb2c38a4862bb387886c1edc1bc37d10f0e15\nA = a3d8b12a2c8f4021ca045a4e4903687dea63ee7e88893b1911aea77efbff00f8f5c7884cbafc71f59fa2636195c2ebee61edbf642923f34d87ba5eb49b06a7ee\nB = 3231829c81b26dcac432b502ce22e126ab564922b1e9818cd3da46edc5ce7df026d0e515809c97bcfdb9666581efbfd364437ba9959dfad099f90472f97c69ec\nM = df8344fa848d1066afe4f8d985cff65441751677dcf3a4e99b40365fc3c978e9\n\nModMul = 30325f7ccbc2c69e11d739ad7132a947c53377aa902ec70b152f3a75e050c244\nA = e4ba620125f58a63fe12fbd3eccdea477d56b120c76d5d1421bebd74e8686b4093f8169070453ccc04b63b173568385313a1d9c841a4aa82a61cb84d4286a941\nB = e87aaa990307855f8e5f2e5509d2ce31dd4b13bb7199cf5fa0593e350326e222efc33a26c69245565d6ebb5a484cfef7d2558f22dea8054d07831d536803d0dd\nM = 43d57108eb0ab9bebaa8ce137628ea825951c6accb9acb7f1e991c93b8563897\n\nModMul = 1975db7b72434ad32c9aee412645f6670b7f4af1f8a424a5031c559d3e18dce6\nA = bd64b1db27fa7da4c92a4ee092f58a2a53ed0f12d009fe13b36d5fd585defe778fafea4a60e8fe567d03e9ba3b72b189e22504ae8ca6aad7c2ac0f44abca2f6\nB = b487d8116198560d6c5b08c7ce63b0acc0c98e6f2a8d709cf4e3a409edd55f64d72fc27a70dc341e280ff5a1b09fe131773d466cb31991d2db23a2a86d225c80\nM = 39d57af763eabe569dac1a103e169e6e3b4375168e41e5c3b961b6e743915923\n\nModMul = 3bbb5bde9e3e240694326571360090e1fc0a4ea7b2311c1e0bd3961f6c159385\nA = 4181ee3bf9a98bcd49eaea243a179cddbf160981efc720685c7be1dfeb5aa552685a2cd46f340e1e1da893b3b460692fa2eaf6c100f24a14f239e45123242d53\nB = 77cd04d86dd5da322af78be54246dd6b7af490d903db1db03cbccde535570b81c6053a84110c07f097540ffe7510320024b7bafb77e9e239761def76092e1d59\nM = f3b9833a303eb540cf8b6cbc3cf16394b1634ef517be57684e42d364d8bec3e5\n\nModMul = 2d8174211f0367233b3a8df7c5bf0066d6aa792be7cdc5e850a477454d5c829f\nA = 1c08cec52d96136fbd9078b7b8db36ab63b86e19dd3dba7b2e3190ff566180e89dfee9423fa4e99be2187eda6aedfa86b9a45eb1e4655257315ae6a280f0a6ee\nB = a8b4bc9647d8df9b7c76cc6d0f2248cdbc41f5da9c061f9864aa8415c9557582cada456cf23cc32d47d1fc1caf19d36b398019aac4734e10f55ce3cad419e5e7\nM = 7eacffe21f88413af94155a2a8e37f70a431a59653738afda04a1bec72d0d9ed\n\n# Regression tests for CVE-2016-7055.\n\nModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9\nA = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nB = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81\nM = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf\n\nModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9\nA = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff", - "9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81\nB = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nM = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf\n\n\n# ModSquare tests.\n#\n# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M.\n\n# Regression test for CVE-2017-3732.\nModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff\n\n# Regression test for CVE-2017-3736.\nModSquare = fe06fe0b06160c09\nA = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff00fcfdfc\n# A in Montgomery form is fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8ffeadbcfc4dae7fff908e92820306b9544d954000000006c000000000000000000000000000000000000000000000000000000000000000000ff030202fffff8ffebdbcfc4dae7fff908e92820306b9544d954000000006c000000ff0302030000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fc00ff02ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00fcfdfcffffffffff000000000000000000ff0302030000000000ffffffffffffffffff00fcfdfdff030202ff00000000ffffffffffffffffff00fcfdfcffffffffff\nM = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffffffff\n\n\n# ModExp tests.\n#\n# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.\n\nModExp = 00\nA = -01\nE = 01\nM = 01\n\nModExp = 01\nA = -02\nE = 01\nM = 03\n\nModExp = 01\nA = -01\nE = 02\nM = 03\n\nModExp = 01\nA = -02\nE = 02\nM = 03\n\nModExp = 00\nA = -03\nE = 02\nM = 03\n\nModExp = 02\nA = -04\nE = 01\nM = 03\n\nModExp = 01\nA = -04\nE = 02\nM = 03\n\n# Regression test for carry propagation bug in sqr8x_reduction.\nModExp = 19324b647d967d644b3219\nA = 050505050505\nE = 02\nM = 414141414141414141414127414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\nModExp = 208f8aa0\nA = 86b49\nE = 2\nM = 30d26ecb\n\nModExp = 27308229\nA = 17591bb\nE = 6\nM = 30d26ecb\n\nModExp = 2bdf498f\nA = 21292626\nE = d\nM = 30d26ecb\n\nModExp = 11317167\nA = 4a655df24\nE = 10\nM = 30d26ecb\n\nModExp = 2e1b88e\nA = da6b761a86\nE = 35\nM = 30d26ecb\n\nModExp = 20a12ec3\nA = ea811\nE = 2\nM = 23bc042f\n\nModExp = c42ced\nA = 1011a6a\nE = 4\nM = 23bc042f\n\nModExp = 4637d79\nA = 28d9a601\nE = 8\nM = 23bc042f\n\nModExp = 20e5669b\nA = 72fe6bc20\nE = 11\nM = 23bc042f\n\nModExp = 142ab9e3\nA = 9a07b9363c\nE = 29\nM = 23bc042f\n\nModExp = 14c64646\nA = 822df\nE = 3\nM = 30915765\n\nModExp = 160e35a2\nA = 15ea542\nE = 5\nM = 30915765\n\nModExp = 2f23a488\nA = 34d2e02e\nE = e\nM = 30915765\n\nModExp = 28e67f93\nA = 636a32703\nE = 14\nM = 30915765\n\nModExp = 29bfeaa5\nA = c8646998e6\nE = 2c\nM = 30915765\n\nModExp = 30959e22\nA = 81dad\nE = 3\nM = 326dd68d\n\nModExp = 1a1da4fa\nA = 116adb9\nE = 5\nM = 326dd68d\n\nModExp = 272bf0d8\nA = 2d21ef08\nE = 8\nM = 326dd68d\n\nModExp = 29f5054b\nA = 76989850a\nE = 16\nM = 326dd68d\n\nModExp = e6c7b77\nA = b88ee70d2a\nE = 3e\nM = 326dd68d\n\nModExp = 369605e1\nA = cf26f\nE = 2\nM = 3ce082eb\n\nModExp = 168a3c5d\nA = 1f82caf\nE = 5\nM = 3ce082eb\n\nModExp = 125c4bb8\nA = 2e9c4c07\nE = 9\nM = 3ce082eb\n\nModExp = 1c5fe761\nA = 523ab37f1\nE = 14\nM = 3ce082eb\n\nModExp = 21703009\nA = dc832165e8\nE = 20\nM = 3ce082eb\n\nModExp = 1228d1e\nA = a5555\nE = 3\nM = 24665b27\n\nModExp = 5226af4\nA = 1077bd6\nE = 4\nM = 24665b27\n\nModExp = 1b14eac1\nA = 2db3a834\nE = f\nM = 24665b27\n\nModExp = 161727bc\nA = 6bd962cb6\nE = 19\nM = 24665b27\n\nModExp = 10d61d0d\nA = c10caed407\nE = 28\nM = 24665b27\n\nModExp = 233da406\nA = b125f\nE = 3\nM", - " = 33509981\n\nModExp = 24032799\nA = 1656b7c\nE = 6\nM = 33509981\n\nModExp = 129ecebe\nA = 2e671504\nE = a\nM = 33509981\n\nModExp = 20c20bac\nA = 4d7a2de44\nE = 1f\nM = 33509981\n\nModExp = 2e3ce9d3\nA = c53b3def4d\nE = 31\nM = 33509981\n\nModExp = 12fadfd6\nA = b4cf8\nE = 2\nM = 36e9d4ae\n\nModExp = 457ac85\nA = 1b1c7e9\nE = 7\nM = 36e9d4ae\n\nModExp = 31debef4\nA = 3a973028\nE = d\nM = 36e9d4ae\n\nModExp = 2333ad93\nA = 552b97c45\nE = 11\nM = 36e9d4ae\n\nModExp = 99ba1fb\nA = 8bfb949cbb\nE = 28\nM = 36e9d4ae\n\nModExp = 27b691de\nA = 93492\nE = 3\nM = 298fdb16\n\nModExp = 3c2b70f\nA = 14e7b0d\nE = 4\nM = 298fdb16\n\nModExp = 1486cda7\nA = 29acff81\nE = c\nM = 298fdb16\n\nModExp = 11725275\nA = 507489205\nE = 13\nM = 298fdb16\n\nModExp = 24d14627\nA = e71c55606d\nE = 35\nM = 298fdb16\n\nModExp = 222b8d14\nA = 9b1a0\nE = 3\nM = 3db59d12\n\nModExp = 3b8bd47d\nA = 13f4e8d\nE = 7\nM = 3db59d12\n\nModExp = 17e72356\nA = 334774ce\nE = a\nM = 3db59d12\n\nModExp = 306447ca\nA = 47079ddd2\nE = 12\nM = 3db59d12\n\nModExp = 90bef3b\nA = a75d62616d\nE = 37\nM = 3db59d12\n\nModExp = 1\nA = cddd44f47e84b3276cc36a5c0d742cc703e61c4756168601fbb1b6eb598c161019562344dd56ab6f603d920a12c360b285e6496a3605a2f8d691c3598233ee9366b5f2692554893bdeb67b7bdaf35ab7273ac593145e26bed82c70ba5793bf4bc5cac4c80b01785d1496beede493806e4f4aa89fd8d41de80dd6d0a3e2742678\nE = 0\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 0\nA = 0\nE = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 5150fb769d5c5d341aaf56639a7bcc77c415fe46439938a2190283409692f29cd080bfe3433005d98d24718a03a3553c8560c5e9c8ed0f53b8945eb18290e1c1a83d919302510f66dd89b58acc2de79ad54b8a30d3e1019d4d222556beefca0821b094ecf104b5e4cfce69d2d520d2abf54f3e393d25ed3d27e8c2e3ca2e5ff9\nA = ead8c5a451541c50cab74de530c89376d9a55c723e0cac3c84b25f0093c08a2961e49ab48966361c42c9f99111587252d98395b76788400d75c66ef208ea2767a28d6f8dc3a859f39c95765d57f139e7fc14f47c908c62df051e7216d379f52028843b4d82ef49133cce8fe671ae179423ac8da5be43b01caaf425cd969300cd\nE = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 1\nA = 935561297d1d90255aef891e2e30aa09935409de3d4a5abc340ac9a9b7dce33e9f5ce407f3a67ec30e0dc30481070823f8542463e46828d9cafb672a506d6753688cbad3d2761079f770c726c0b957071a30876c4d448e884b647833befbcd6b582787bf769d63cf55e68c7b869a0b86374f8920516cf5d528f348b6057450a1\nE = 0\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = 0\nA = 0\nE = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = bbad67352704a6321809f742826bf3d1c31c0ad057bf81432abeb30dc9913c896c03e69eb1cde6b78ffcb320c4625bd38ef23a08d6c64dc86aec951b72d74b097e209ce63092959894614e3865a6153ec0ff6fda639e44071a33763f6b18edc1c22094c3f844f04a86d414c4cb618e9812991c61289360c7ba60f190f75038d0\nA = 855144760f2be2f2038d8ff628f03a902ae2e07736f2695ec980f84a1781665ab65e2b4e53d31856f431a32fd58d8a7727acee54cc54a62161b035c0293714ca294e2161ea4a48660bf084b885f504ad23ea338030460310bd19186be9030ab5136f09fe6a9223962bce385aaaf9c39fe6ed6d005fa96163fe15cdfa08fc914d\nE = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = 1\nA = 9d92629c1ab181c50c31619e8acd0d235a1f5fc7a0bef4d4fd54b4f1968d45921f8522efe88e69c6c14c576c564592b9feb00d1554b88b038934eaf4a8ce81a2582732387490181ef158360c8b2d9ccb326ffe043f776a50cb8202837f08ca743b562eefa007150ab7012c341b16248478d4775c02ad71ea13d5e82b71e2d600\nE = 0\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 0\nA = 0\nE = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 24eaead5b57883c2f454928f8edd470a344bfe07a953194f7d635d705ef13ddfc64140c8ad6f363d4c828e7c7891a6b6d4df37335de4552c319dafd1c06d1f743240082a3535df4da1475d3eea3fead20e40815fd5a0876c881c162ab65a1eda494280c258901ca953d1d039a998bf0e9aa09273bbef4865f3054663b72d75ff\nA = a31618b4532f53729ba22efb2221432fab1dbb70853d6a1159b42fd19fc949965c709b209de106a652aa422d88922ce51dae47f7f6deaf0055202e13db79ee84fc3d3c6f4c003ef96597c49d6895fa53c22ac9e4819f7048146b5272f6279424fdb389819a0b251c823c76f4bebf4f1246de455aafe82a0d34454f5039e90839\nE = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 1\nA = a8558e7f455b27c0c46d7d0862eb409cdefbeca945e0284b5bf425b7ac0f3d316bc365594cc1639decffc621214d61479bc75135120d4ac09ea8b742ad7ec1822091b62b1c6f564fe5e2f4f5b7def92cbaaa9a898549207ab01b91c2324fbd306a87f7d6379b6fb6493c5fca76729767f136120da9c90bdc7d364f7d242d5acc\nE = 0\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 0\nA = 0\nE = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f", - "\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 292f0b39ca0f1c850b1a00cffd2d54924fcd5fc7e7504c9d593e6c0ff74760b1f4bdd81679fe06c50248336f3108c593fa111072ee87d0fcc89a63243a1dc89044503663eee9bc18f51c3e0193d9108303e12ac90ff78f6ec752a4386af09c42db524a7cbe9a3d4fcccd56c34d283bcc9debc17158b5fe8df0c1888a9841bf8f\nA = b4fde2908745ff92cc5826a27dcfdda09e8fffee681844fa4c7f1354d946d5d84e0e0c7a4a4cb20943d9c73dd707ca47d796945d6f6b55933b615e2c522f5dfc33e0652917b4809bab86f4fa56b32b746c177764895492d0a6a699812b2827fe701d40ef7effd78ea8efe1cac15ff74a295a09614bf04cae1a5017872ba22efe\nE = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 1\nA = e2845c572b46496ac158a731f612fd40ef626fa7134755c25b1b7614f4d7b29164e6142ddb7985e4c7ebc575855ff901e95927fe98a5aea2ad3a4720c75782323bea1518b2c57790f44efd9411be4e95b3896bad1e73c59658290b309e5a7eb5ef8be08125063e57336b80f17eacee88966d12bbaaa15a25929c82e027cf696f\nE = 0\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = 0\nA = 0\nE = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = c90e4c69df92e26549b016950b59080947f5403430698e128477782480dd70be96bed2b9042dd8c708eb432e02710555b97af11ce6fa9b53395022851c32d1f53f04237fb0763563b440ca6e81a50d909d907d9c26b7d3c420dbf88f7dadd488666848135f8cdc608dcfb0691989289fb54379c2e84c262f9765f68c012ca1b9\nA = 882ea1b9b6c79a3b1bdfd284658cb6227ad825e0178cab713c7413c2ec34f03cfaec470c4f5c521f5e9899a2123878ff0f5b36a4196c08ad1b04d03746c4bfb5d126f5eefbfe172627d6732710a8ac8890cedbd4fdef69a19f2b3253a5aa0e5dd5484f72d59b17bdd1dad3db209a3ab839368ed3975069685911d7b35e41a9e6\nE = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = 1\nA = d7a99e65b8af86b1c51d851f0447e43cd4f343cb0ada7236283e69aa7ebd383826acc9809e5dbc4002d0f2430022cb026458189db3805ce2de1142a31ba71a6c064ab51f0059eb4b931b8bcbaef023c38d57aa5f3e14f5df77e547fc028702071b58bd57338be1e1e4f98d3553484e4de359cefa29c5f58d3fa5d823f389dbef\nE = 0\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 0\nA = 0\nE = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 186c50ae259aa0fd31859cbcfea534e626a254de33956d5d719334bb32e7cf37cf199a21f079a5b90497228994d05efe19ccd8c769cd81f896286e8ae557cacd1630a928c629ecdfece29ab3697794aa707734e007318fa7029b050bb09ebbe6986187c6ca843f55266d275620b3f0fec0ad5f847ce8b314d929d128b33a249e\nA = 9d5e345793faddca9867f23eeddf6816c1e837f7a2cf96fa077212514acb6be87ac01a237d8f2f1d07d27a8ddd1b0ae0d97e1bda4f205a89435017284cdedea3e407b1b940d6f52112b6359b3e86e4c83074b17c210ae2c8856b42b169b4a7a6dfa65b368a7959496cf9bb1ee93d019dbd79101830e3f5ed08604ab90890b914\nE = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 1\nA = e6a079bdf7b0638d50b183475e9ddfd5cbdebfb29f5fae8e9be402a0bd36085737b556492ea7fb4b1000ae9ce59db66098129b757cfb29224275fdaa46b8b7eb18a93ca7d3e446dc38c734b683d7ba7927b008d993aab01f44239d3c76be76d1503908e9b5e73b36c43ae0771368b01f39c042693bd92c4fc50810f059e1b332\nE = 0\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 0\nA = 0\nE = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 60719701a2dc0bcde281a93ce0b8421d1a718adee43c1b5d9fe9e697a48ab3db4f9f33c73cff305ab6b6c300c149b05c6b289dce4580860dc56bc59de81ac074ecebdc65aa3ca040b44e5b3c80ddba1658d78b9abbc4c77e5f171f5582e70ab4438a8e1e2f062d618c4ad09c70c73b5b5fbc9f8f0bbdf1d530a933b705f85af8\nA = e1b400cd3b1f2f1c6b437adfdb970d2c8108f1b39bdbb13582179552011c6c97cba6bff2c463212b7f62776aa3e3aff9f175990e79395e819c144350b0a23d61638d500ecc97726b098e1af334aece23a851c718612442c04eb7b3805a24cc8f5b90042145eb5e5d6a408092832b6bbeb8a621419a9282fb5c075f41c7f1fdc1\nE = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 1\nA = 9dd1e6f2d3ff24096b54e0ebf0f10e283e484a1cbafc0431adda1296ed97692f3ba99440fd4f67c96dd8bab850e1123361c99362df9ea205ff8e90d1b329459f54730992d5a360e46fcc5f5a909e691abb9a06613d6991bd7c2aa609f0d7b441d7ded0c07b8c394327672d38a905efb2d76aa3be5bb14d0c002aa37e287aee79\nE = 0\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb", - "917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 0\nA = 0\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 86fb0b8dc161c41de2adb0f3ddcc8ad49c1efd729a52793a3ac987d4011c9c1dadb18657dca718df75c8ddcc49d60f152c46ab85ae9076ee7bfd405679a7da3a5195a1bbfd7d2b998c7b135ea91f8c445cbafe1276fa502c2a85477716829a2e0d24ba02623405a3654bed8f355bc7ccdb67c3f9a01e249e358b60d7699498a9\nA = 816610e6018ca47074d55750dd16a281019dbf95dc752605794cbb8ea8d75775317ce685737859728320b529fb3b4414b40bf3a93d08d8994a21ae54682cc1c357eb529837a7b0129a0843eebd9341c9bee3a8ae30475bdbff517e885a0c9f2b6a680643bd981efb53bf9dd49f3dc3cb757e117895fb34b1b4336d9bf8384558\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 1\nA = 9edfce4691f46eadaa2043c7b1092b831ed50f3429f0bca02f985c0b77c686d951be84d772ae4b55f08935bed6e3206c8441574f215736b5c1c1b7595b3b789b55cf56db83741b10144d6767ba2b97b23a5e83504c60e06ab22834b0145655aa0463108317a379cbfc8a93de8a66925a999b8b02bf88dd85fb9898cefe9c95c8\nE = 0\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 0\nA = 0\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 442866609915aa6f1bae9dfb59e721e1b63f42c0f75fbf0a88344120fbbd7aacf15208fb7c9d8bb8477d553cbd826d7e685ad764a8423e81c2131c040ee83a03cab8d5ce50866a941b48c78e9f1330794d908562d4141cfbf26e8c80c69551339eec41e37e2b37b54330f7bd75748f8d26d56ab9eb3b0c127540484c6445a7fa\nA = 8ff65e2cbcbcd8697cc3ce9a26855d6422ac7eb4e66500648c08be697e005cc3c854a54cfab91d43489cd60be8b516a9b3c9688e5e009a1689c6b164a133859a5464ef422c86344fef42cc477c9df27768377c126a066d1b62f593b7f6d6e906feaee16addb7cfbfc043d741b7dc81a87c17f167b7b8ef1b1fb3dfd1eb14102d\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 1\nA = fe9f77f7d0475e00ec964c0effb9b8e079c32e376ce77a9c40ce4018c3df44a77b4f294d9565502b2b79accb30cb58dda6d15e1543b6d4a53296543ed11c7f51baab60283ef03fae37dfeacb431392487ec2839551a933895c4dbf18844f7b375d3e6f558d3c39993cea1bbf7fb743a6a07bd3753c03eb7298811476d7f3ff1d\nE = 0\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 0\nA = 0\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 91fd879d02f95a9f40fcd1037726f73892caf84e9b43b4aa4126d9062a0d22c464e7af2fbd91aa849612d99d9519b724a7fb1cb018fffdcff321d883ab2519953c9f174f09dd8f13ac87339887385966eb4a94842276637b2c36c0a5036b1d3bbea438bc6efd4b4851c7ec06879d60694df894717569bcd31c4b13d80df6cbca\nA = cdec5edc1cb3ea974342b85aabc0f9385cf877ca328747d40dd4d297623ad69ab6582653faeed5aef225208305135cfbee32e066cb43e18afacea3a32acc8aabbc49617ac33e741651924ae56dd6aa044a12a1ea50fef573b5befb2f4b21b9cf83ab2aaa6fd153580a0761666ade8fb94f202a3c3dc4f33297eabb4564374168\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\n# Craft inputs whose Montgomery representation is 1, i.e., shorter than M, in\n# order to test the const time precomputation scattering/gathering.\n\nModExp = 9442d2eca2905ad796383947b14ddfcc341f5be8fec079135c36f6f0d9b8b2212f43e08bf29c46167ff0fe16b247cd365df4417d96cc31c94db1cf44b73b0ee3ebcc4920d9b0d003b68e49c1df91e61bc7758a8a1d2d6192ff4e1590b1a792f8be3a1b83db3ad9667d14398d873faf5d885ec3a2bef955026fae6dbf64daea2b\nA = 3a4b4c57e62c5e9d1a9065191f8268fed9d5f6f424d071acef66f0662b8210f4c029ed991512e40c9c912043c816d2c4c5b53fa0e5c253e16808aad4225130dafbbb89fd4f30cdfc1c2f2179b636a7ddc4be579795820b4b9377637bd8a21a0ef5a90d0e0f865321eee23d9be2a3b7320b4012d02941b892df2c40bdc85c1898\nE = a2c56ea1362511cac0301918e15a9afe7d37edd438a5c3538d258ea01f0a6df758de07111e868b3ad8fc89b629b4955d78a1b3af902be1806410ddde25ccc6a196ba5949395c1ad5d8725b18815dc1cd5ac1c7dd17773f571e3f2e628255af14476e0494be23a4a4dfd18e23142f33d7a59c236fec61660e360d9676a747c69f\nM = ede35a3a7afac817d413373a2032abbc067b1493f709ae6e1282ee5469743391d891b904938857168802b7872d3cd7ac18ab249a9e540a86f970b1d0f310a4cc29df1cc9d4063d98c554f1a32f4ca5eba3523cdfb142e0fc609907c7a92bb0187009d97ec471db3545f42dd5fd29c07b7816085d09477ba31fcf90084660116d\n\nModExp = a7f5844fa9e7202d4b70ee252c9846e63d3d091b0387768ded872cec53458e19df0d9b4960226e269b8ca5dd4c4eda423a67b6dbb48235c08c12c6c7c78db47287756d3ed9cecb9232f7d18d5d80b9676cb68ba4a290c97e220beb1a069976b5e6022a4c1e5ddbeec86b62dda24ffea1deda37695c9f61a8817218e6370c0679\nA = 7d6d0cc947ceb949cdc4e9e1044f5deca5bb05a491041e0d85bc4b92a0944a57c72845fad91e59010c61ad1712bd2f612d53a846a044632262a9f2e3373b062fde2484e0c165ff947f2469f743ab6e2e5e13c640fc4029b1c9213eb8473c674e7f9e95a4a5c5636d4656c1e696962340d77b322daba47d6fc894f2a2cd9e0afc\nE = b78012afe806e2344d004c739c97324256850980ac97d88c4ed9a838517639ca112e235978d21a176c33f5a68703aba0f2a05501bbe3fc8d49a000fbf530cdb431581dfaf8683cb15a2aee5e239cbc542827100da3b47babf4a16ca7c588aff9912e674abb449e0b767a15e415f4e7f2bbd6380d7131da3df8d49b13bfd35ce3\nM = b72d5c55bd2998472f1965e75a51be6155c1ba04656da8f66bcb34db36a7b1db66a89d1d05b1bde10206acf85be7b474ab689220faf1bb52ab39d8dc00512dd4e26df1179c11b973e1274db85a88c7cc2a17113abdffe58cb930ddc5f3ccc4d68b4e65c913730509f7ce5656e8bbaba9b1be177ab9f766678f018fea05da9cdf\n\nModExp = 465ff295786a88496828fdc763e9292d557", - "957544e9322b7996807b87fdbfa7a11614bffeec557ca831c4824c8e4ca3b1a1c7f3f4f95ec3fd6a86b73bb13d78b73af2b3c7e76954d0cc03bcb0cd606867ebb3765a8b3d0108cbe4f343a14016be9c33f6d200f0dc547e7d6b02bfab1e79dcdf9c9835a814cc6c855a12ebeb66d\nA = 89ad02bea3e9ab839a6e23f20122409daba52c68e1e893034b30d321c0305434a6af940015e3fa5ca9c35230da34beeb1ed4fbce6c1da3a8bfe3f3ae172276c1d1723b47ee61e6f8fcfdafad102d6f7ee2a79f510c7edb93096205a40a6c9e665b88b18f39a979e2e61286d939952a6f02fe8148b7515bb25f4252337cb6e60d\nE = cbd6ac628cc7afa3c61bee9c22a06a395087ec1811fe9681b55216700c435996c815e7cec8aaa90016dd2382d0306a5414630124e14f3d396a4ba02ee17851bf720f1607ff813e4bbddf01338983db12f59bd6371a738eee3eeb716f21051d6174d2d6c77602942b9edaac18d4b3a723096c0d00dd23a8a605c585022f311560\nM = fa7a3e40364c8a8d0f14f0213a3f3e035222ca0ea19d46d10ba41580e5dd2805c8a133f3856d7d5d97f922ea540e5eb0d10ad04dfdbb74f518f58da0099a6fc2b3f3def92985176e07fc78aff2faebccca10a429794e5f15ff92f75fe90f527c60ddea8093a9078c703c372ca09f7aeb27ade02f3595308c61dd9c44e62fd101\n\nModExp = cf08bf00261402102e9fe03f3074471dcf0e9b3c96d4d1503f099f24ec85e1901b023e9e048c1ad042244f5f70b38b25a99f4c0a7b57d5844bb0d0137367f45f4ce2cc7746105b77414768cb97648dc5721149aed2d4c682408cc0d50d26dd0bd77e848911f8625c727cac5f32e63bcb548f41a57d718d772f23983a42f603bd\nA = a419646a6631c2c69b18f7aa65011825eb31692eecaee9d74f92d92203811b68e9764bda31a1585bdf69b6273fc6f9f508c395ac081336506525dad88473512f08a205621ac8b16e9864c7a7c5a4f17435de00d0b32badec6ce4897e3e1076c562b6d9523f63d0b2079eaa416cb090471657763f24931d955d1fa2720c80a9c9\nE = d5a6f4a1842aaee39805356dc8d0d678ee03b2c81277345beccb2742f899132feb43271f95968a01ae68aa8277201851992dc0aa7a71c90aae71b124d873ee264ea400fb131be0fc6c4ce8c04c45f6bdaca89ac743635caf6158983d257e21cef6800d7f990e912ba21bbfb8fb779afa4abd19e07e7e07eee9908493d1ca502c\nM = e739689b6cc6def1d45fb1a2ab551643beeb303f4aaa4da47ee5e4948510f8445b4c40e99ae8354dede60b2ba6694e93bc4d573b7e8adf871b7a9a9636eb7d70f2e49328e2d7978143b177cee8374ef01bd1ee2d95862765883f5e7971668b53ef0ff41b6539faf63c397522b0bdce916388e72e26c8d3d2e58dadeb9eb5d479\n\nModExp = 827e6312ec3b14600203bb83f5b277ded197b2967363630ef673240df05edd3ba8ab2b11c86251a612206569c6c33952b31e264f129909bfe723bd0ee1624b36cfcfaa893a6ec8b5a1f7de79f83e79b459a3350f89f412ad1cfd6bc4c2a7a29272c783d6ecceeb1398fa17041835643f4debef9b5e87b098d104bb8912dddf7c\nA = b8e49c637829021d32db3a39a0c1e58cdd4c6e4eda7e8e9293be379e9c2e2d184f929d278598a81ae231cfedcf69cce4a6e31cda3c8ac14d753a7311f2436e29795f0dfb60259a0f61a997918ff984aa2284b43a9d64c974059e9682adfffd018305835f74eda8c75fe4877d811c1620f654ec9f7f32d1af5ce59115e2f41785\nE = 80e0febf369d234bf1aaad4f82df2e2ff02882c3184781f6ccdf4f7cd93b6887af86830077c84dfb02109ada05b40970b1c65228b0c19030bd6361c3537fee22a8155c03b4e7007ca006c6daa3659518d05bb81ea0079456d0ef6116df248dffdb0c935f321f5a1034deefd5a9414a0652aa6548de33325b474b9e5a8507a082\nM = d5eb1d14af842a9973274f7463d90cf0ccff19c47d710edbae184478d4f29b02693ed7958bd487054327b9e6d8879e24c9af7730b92f323eeac05558da6c1b952e5dbf13de236050a77628bb5325fe0d14cc5773bf73338759d5ab43c212b414581280f1cee250007e53791b800b61c90de0328acd7bc43fbdda48158939392d\n\nModExp = 4a1efd29c7e78549f5cd4deed1454b37462c7810ee6a8a2493b764dfa479be13b314cf9ff98259517d61865567ef499a511630c0038c97914625df181c6fe07892f329f98b344a78d751e9471483eebaa7977371bf97bb25187ae7e93a9227d6c124ccb4644423c961a11ae59c4354f89d5a95164c23d9aa256e289e9cc0858e\nA = bd86c9211fa6a47a06e5016c46cb8a99e34a043a29e22f8c3196fa7197c26b38927b8d9bc0ddc11a5fa4bcc44deb69dbf37cbe7ebc9a2fad6c74e09ab5a9dd929fa04ab4319b6caad1035739be78ba631fb0748d9e53944836d37ccda6e6a62823c696d8f31139ccd7f2f86b22fa026ecf433cfb1271a3539ac4f1c83aaac059\nE = c40b9972006d28a84c2769a86e526a2b274f73afc7c5c6a2742166757f61b5f5fdbb228afa157af62af989ffe966f232bba9e6beef5403d1690ade31a6410f7f349a35bc4267a129afd647993df7d45cc0e1a1ba4678d7f1b6e8a344d8ff7037679e1f4db25a454e4246f6b55c416567fcfa188e8a3865115851d9edf0aa8902\nM = cf424d7af75ce7eef90cad75ae55ca8810cc7b4703fdb5bce701e7bac07e0c371cae06df2aa8facb55a0faa6793e4d2bd9d7969703743b9be170be82792aeea55e2bc0f7ab7617b276486bf474dee2f4556aab595ff3ef115139cfe5e21ccd4ee05c0e1cf901bd85df86cc17195a783b0be836d00bee82ce064077f9191188f9\n\nModExp = 3137a3049fd4ad2e26d870f5c998cf11bfe82101884a82e85e43facd0928cd7434a2e346ca124619769fa141bbe92ad6f36b99231032ddaec3b349a410f82b5ca36f45e56e5fb85dc63d32053dc90805d3f1854ab385281a71a57726bf97158494e7476057214ca7379ab8b70f5bdc15f70bdad3adf33c3a1f9cd1b6bbbad556\nA = 39a1dc6a4c3f14d9c350ee968d5ce139ef725952c967a2d1bedf48ace22091283525be03807e2e263d2640be77f0525247bcd07149bba50568cec5a082c87d72962cf9e43bcb5cdb1e7e9a650fb53e0ec2fad37f09a9f036c0d7dfa528fef846769f80a9a60854910ca1b4ee05dba82ed2ee018348d6b3e52a764b8ffae61e0\nE = deaee3a3f80c9f684ed7110c0653847ccc7be5ff6d982fd4b49f59b5dd35f7210b1077babbcedbc127df35cd469dc6e569a0f84e58149b5605c94b09fd7f0b098d02b4a04631328b3fae39e6c2fce25334225cab71829abdb9507cb903701559660f2c08c3b743336119d1260a0db27054cad3f28bc1b04b2289baa58fb33965\nM = 938388927d06ed3bb1286c0f06d3054cb0ee16dc7a0bbbf13a45293c09a5f40f1d611b2e1a1b0ec2ef109b508e27af4274954905cae52034f8740a744153b4d22059f0dd262ea51785522098ecacced6da07709ee6b5acc8c4e99331379a7c3de7f4e2d1431e43b19570140955b7bcba118dfbaa552cbfa2be531e8f781166ed\n\nModExp = c15ae334455d9f4d1030cd33e734726a27c63624c2afc576238cce5e0498298a4a0c93090a0d19568b41290303c4b558f3d9dd74f9cde8798710f68569ea0d6fd971ce67ec5b54495031de3d8842b8b49288725bee5c9f72b99054d64986ccd4e18d70d5f33943f08cd694eff538f84438ea993ebaba0910c95b3a694f213510\nA = def633b955a917569df3ba8517455eef0655e7a35985edda27097a063e0d82c7c3a76dc36c5d8a71ba9d540790ddd0ea514aaed98925f9a1808eb288d387aaf9605a9ef8a333ebee7ad7057bca012efd619d5867f02266f65976ef4b16da17468426ac4f99b3e8921707e01b4de20f6f9a068e6a19d872079a27f3a44449db83\nE = a465c47b0d15d48e01bb8b1d8e3b3253e11515f6874dbed6c25818adf1a8fd927124d5593beb367f685c11e46f18415be73ccdf16fa2e93a600b728163d21d232849e5278c3749d903edad3f1c4535a2f55a2ab65e7ebc64888bd2a0527e876ecf38cec3ab1980d08138709fad8eb88ae65d960adc3f0f8e92f784fe96fcb693\nM = e43cb9ac1446154356cdc31ec771c79b0e461e22d95185bbe1a279c0945e3af07903a0cb54d553380716fcdcafb4b7cf5dc6da481dc74a8c583d75ff6c1f8e429182d200246ebc473bb56e173787987c1b7fb2dd23f5b2e438a97bc4a1df628bc044fdd1e80c0cf37030adb7b04784dab827d0dcd64f0dbf37c980612570ce11\n\nModExp = 75c3f79ab7c991b98e65505342a8a563cfb08b5d3ccf8664c7db1de50256b1d17ebf7096dc98c7bb5d7f027a894ae5cbb14dee04d5d445e775ad7e239acc82673b0ac2d819a69c83864f34e73d9a636f05de8279619a067b4c90ad038db5910447e03841d2034635018f08cbcd21efa00994247763a249082594128112f95232\nA = 34def7d76f6f158a359fd12759fb889cdf6af0a24830dc3e84283a1ab4e9b2647a6a36b86482f829b2cdf3e3d6028f9a884b1f64f7262315446bea8b0231828e2f3d990fb103c17f820b39e4b8427c85643ceeca8f5dc8f191d1255768300e859bd7d88c770319ef38269660d221cb3bc061389b6fc0783485ef042b1c7d6fef\nE = c6c46453dd5aac6b37277a446b1d0c69cbe476eeff55b3ac35edb89ba97116b0e7783660f2c7b31b2a2d6c4709d0ab45d01a838100694b0777c9c9c14c959b07c437c73a5eabb7402f1001e802d797a2e7707285834fb6440a1c2f727f7bb84ddb2a49312d32fa0ce620c43872655cb5c394749c9e75d7fa25be00efe50d47d6\nM = fbbab6698a9142095c46b38a732592e4366c1838b84bf40f8c8fc7b630f73380a0d09765562365798f8c8030ed1b6728329d8bb06e882c35a1d59bfe84146a9db2afe42a414014e247390281c782fce806d62adb54778d2bcb49555459429d6ed446af5359657667f6aa19e8e3e0e24ab2bc312b2d90b5cb1ce6f2f15af15d9d\n\nModExp = ba16d7f3f6e162ce248490d164a13c00e7720d8a667e2d3ebeb13f1663e15ef5408d5b56cbc7bc793a8ca787cc50f8e15e0e9d4ee764531d04a9114eea556bb3e206ed7d85267151a056b6e68fbf35e03f2cf829708ffe1de13e95ecfe365aff1eea36340ffcd3892dee659fb1ecbe50f5080e54737c10f9c1ba638b14ef537e\nA = 9025e6183706105e948b1b0edf922f9011b9e11887d70adb00b26f272b9e76a38f3099084d9cccf12d04b1a99c0f654f8b9ed90c6dff9478c60bf05d58d734ab60eaefa14a22230ec60c90dc1f0704b61eef0bef345785ae0e6a9af7db069cf6bd2b4e0fe58a0ade83c7e46a04b9fe1d24cb9b65c6f80de713e61d70eae5b286\nE = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae159400943725570726cdc92b3ea94f9f206729516fdda83e31d815b0c7720e7598a91d992273e3bd8ac413b441d8f1dfe5aa7c3bf3ef573adc38292676217467731e6cf440a59611b8110af88d3e62f60209b513b01fbb69a097458ad02096b5e38f0\nM = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31", - "515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7\n\n\n# RSAZ 512-bit.\n#\n# These are regression tests for code which historically reached the RSAZ-512\n# code. That has since been removed, but the test vectors remain. Note that the\n# lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 7f34c1cd63377bc3abf2bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4\nA = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same as above except A is negative.\nModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd\nA = -8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25\nA = -80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n\n# RSAZ 1024-bit.\n# Note that the lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7\nA = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# Same as above except A is negative.\nModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10\nA = -21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nA = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c1", - "6f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d\nA = -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Regression test for CVE-2017-3738.\nModExp = d360792bd8210786607817c3dda64cc38c8d0f25569597cb1f363c7919a0c3587baff01a2283edaeb04fc288ac0ab3f279b2a89ffcb452d8bdf72422a9f9780f4aa702dc964cf033149d3a339883062cab8564aebdbfac0bf68985e522c6fe545b346044690c525ca85d3f4eb3e3c25cdf541545afc84a309e9b1d7807003461\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020df\nE = 2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020FF2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020ff\n\n\n# Exp tests.\n#\n# These test vectors satisfy A ^ E = Exp.\n\nExp = aa6d7ac431\nA = d0e07\nE = 2\n\nExp = 12d416b110dbb4e467ff0c89a22122f4da8240\nA = 1a18cf6\nE = 6\n\nExp = 49a3b33e23d84f1ce0d5d83f5dcb651d50cf3920f0143da2310d0512a90a06cd8f38977df8a756c30883de38df092000\nA = 2a3acbd2\nE = d\n\nExp = 5b4a0d5a956f885f275712b194459980f24708bfb6393d71bd37dce852ce455724f5ee5030775fb86b4295edc98afaafc097e4d82a97c0078ec0eac763db16549c5145c4cf2d3124f88cf9a5c71da0625afb99b26801786fe49a778415dc025954021753d08691947a208b613f0be5c1\nA = 54b3ae461\nE = 1a\n\nExp = a0ea5f6a4de49beb8fb7f0dab280d6a32c5a3814c9a5153a7944cec0a9028497846a8a89044348721a0bb5f0c3ded3e980574ea321b0cdb0ead4f4e93841ea7478a7f15d9729b646a8165813a0750e8124f5465dda9b105e1bbeff18fd09c09a2e26610d9176d253b877c3a8908a6be521cbe1e472a7a1b7820e4e890f8f28aacd34609c686e76e15b01bd9324a71290812724ea564d11c874a6765b262c3e57d479da0287a76026a1e8fe53da0b02405da1d379eaa30fc65f\nA = fccec0f6df\nE = 25\n\n\n# ModSqrt tests.\n#\n# These test vectors satisfy ModSqrt * ModSqrt = A (mod P) with P a prime.\n# ModSqrt is in [0, (P-1)/2].\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 5\n\nModSqrt = 1\nA = -4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 2\nA = 4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 2\nA = 4\nP = 7\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 4\nA = 10\nP = b\n\nModSqrt = 0\nA = 0\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 2\nA = 4\nP = b\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 3\nA = 9\nP = d\n\nModSqrt = 8\nA = d\nP = 11\n\nModSqrt = 6\nA = df\nP = 11\n\nModSqrt = 4\nA = 10\nP = 11\n\nModSqrt = 5\nA = 90\nP = 11\n\nModSqrt = 3\nA = 80\nP = 11\n\nModSqrt = 9\nA = -e\nP = 13\n\nModSqrt = 7\nA = 7d\nP = 13\n\nModSqrt = 6\nA = 37\nP = 13\n\nModSqrt = 1\nA = 1\nP = 13\n\nModSqrt = 8\nA = 1a\nP = 13\n\nModSqrt = 54d4cf0fafe265056a29016778cea6b712bc66a132fb5e6b6865e9b49e4c97ec\nA = 599c10484b22d0b5a115268c7538ca99b3253a311a4ab1ca11c3665b0bec393a1167d1ad94fb84cb2c7ad7e2c933e8f613bdd08fe1f1aa4a9b0b9de0c8a7c9d4\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 38a7365a15365e911286c1be2a7afe76ef390234d76269e04dee17313f6ea54d\nA = 1c4aabb4d8369710131c664ecf2849e963c1bc31d66e0b939bacf99a870c71f24ed71bdddcf566f3908271fee43fc1ebb51eac7e3153efae641b49d2e796a12a\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 35ab18a560dece04725667f640ca61d1d59f14d191f94c79f58531acd097d444\nA = 685168ae855d60eba220d803f5296459b30a289580668db9ed51bca51cc2d453a937e13819ae34f7a9a143ac96d17420c53919167e46279b562b550be1cd9abc\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 288370029e87024175e5bec0eab0929179f42e16995e7f6194eefc61061e54f4\nA = 2a14ab77c045bdc48220ba9c463e1a4b4049cb01edb53be0937767eb2ec19b7d719855052281250a36a0b76d9a5d967d0756e1ded7a052f7056191ad66bcfc9\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 32255cf01dc943577ec2bcb221b98491d7a1130d046d6c68e95fedff643ce3a4\nA = e26f6dd46a513a1dd3fb14b71be1d4c9e9d79eda1cde10ea4d1eb8abfd4d5857572205e247184dd0cbefa37b5c0bf680ba2bd28c5741f725cfe2aae37419baf\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 5172345e801ada63fbc4782e32583cc3b4fea88b9e6dfd542f3542f8538ade66\nA = 40dafa8342b302bb04b1f3ddb3b9015a8fc1b597857c115b40631c7be9e22de89358fca23b331596ee5ff304dad7811e6d8e8822f7aa533c9e7c882634ea550\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 4dcf63c423bf0e39aca2293d57f6792d023db649d6719fe936446904b9f7e60d\nA = 5bcdb514bbe84261e169203e8017909b60c9bb330400c766ee01b0189378e70e61867a164a12643ddc9e94b61e09e5b158cbe85be228a3cc48f95a552958b8f2\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = cf77c5c2d12a500b75cbfb1f3e66ee75d886b9365cf4f8b4d1bd18a6be0f387\nA = 4652ddc2ea7b460d8ec3c9059b8f9b5dae6cac55b51f2ad86fcb336b25235737965cc515e2ff0b54835015b7ebeeda6fadd986471d8cb424d309fc353d1e269\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 1e0549e4c5a26023e9d24fd8c67419960746f82b1ecd113bdac66f570a475d87\nA = 5f4a6d450ab1390d96ab1deaa0ba18f897cb63daf0c9e1ef6c08e804c26b5e842f6c08f13db5d4a6e88f07af2a3cb04fa06fc3e59c410b9356f025ed81acc74\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 144481a781d831c1ca046ca9e322d79ad4d2c6dd9f780bea9d1ced9cd20b7b23\nA = 4c254fabca441017132b9eacd4ca40a336db3e5c09715773fa07af095989a91cc968ff07a9ff56ed06b0ce0c5269f7b2ab68564ecab9f4467a7e96b6cc6b21b7\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 216fecc7667f488a3d2d102a38b46b4860ab858300b8638af4f34e1103fd73ba\nA = 17878f8048227573a9d", - "70f53c0e76ff13fe9f56e9c984c92514d3d13dec23c816661f0618d21371b80dfd885cb59551bdf80046f65f22ea9b89c78645a6e455a\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 458e5e789ccd2417174f7e30bb31914b9656bd8cf2b9f5a9752a8737a67707bc\nA = 5c7d39a4bb04e69201aa519f80ee7e62ea14ca55e13656d1da3f45367e2fb2d061aa2940708d02ac67d35cd2ccf54a1bf95bcbc759779e692cfdcbb3aa1a05b\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 543125a16c2bb8b8f8a2c39c497e5224ec77533602d7dbe24002e32dcbd2ef1a\nA = 3413afae333b2ad9ff45c7f3c7e5934b3127e8b1a55225958ee6ccf42423e81559bf070ad3f3353b78c0ffd41475af49f59d268ef78bdae879f5155e8d1cc07\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 10e16859c67bdb2eaab52a7c847dbf37162eda258a9f6262ebacfe4cbbbc1080\nA = 21ce7905894faf220bdf4a82a2d855994ca2dc9feaecaa53c7f146e1f49934215695e9bb46ba370b7005a90c399674caa8969eb442e7914d90f749774d7fd194\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 32a00586adc6f6cc2b1a04e1be0ab569fde235e1436c38b6af92bc5ebd60bc1c\nA = 350da4fd8cf03c12f7dd6ac6d3ab801a3413964083e374662aaf878d6838b97d4feb9e52cd307a25b113e101661a865463ee2480c626aa4e2ec437d72e7bae4c\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 971f75bc7afa8b4b50f1d4b05e52deac7d4836a08d30546f29649bf1ca6a247\nA = 655ed4c5d8d0afb4f9360372ee1ef1303898d2423e585108a3303faedb55064d2ef25666ed4c4d71fe6063fea1f3142b435714b0e30b339dd791d347c884654\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 48fa882b7cb6a29de9e3769f72eb67f1efd4d2af56f0c7e410c610efcbce2065\nA = 14f3503f33b243800eac1defaab33e04c01e80163fb3efd03860970cc016832431ca4fc6d1b760f4f40166b0b8b3c40dbebc81460cc10890172243770338f090\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 236fd7e397ea7f8bc2a288eb7236ca41936fa702b7dccca56c8852e147511f7d\nA = 1bbd0980feac854782813bcde4da85e8a054549a1b515e065da4236528035e756882e29e762cf60453e375cca9dc6ff637f9558bf86646e3b928f68f82af7efe\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 693f0cbe8c81b0afde0cd2f83e53795dcae6b0cc4ba930ab5c752400d787f14\nA = 7b20f9664b23907e152ab8c9a907f72e8670c1c38ab4cd1411ea7c2159c09aa131afe068929b8e6ad1409b74c04975180d1cd0a9fa74e923c3fd451e8da2c34\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 4a086c50b0bad576501ddb6280743b2c9d247841eb7f14d90561432ff7dca6f0\nA = 4367431ec0cd0d7626538b93a090c30fe0c97c18ca03b97ddae304b619112b5b4d02bf0f041fa3fd673f9ef2ceb07eb2079d11c56dd903b1a87e8252a97b8079\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 18f8433fa468d8065157708f1f1e53b8e31d39c6011fbc2bad93de1b5548e19c\nA = 739c032bb4139c199c40f548d37234298772e4ccb9d3ba28412b60ad23b4c465b0787e2382f1c5a4a87af2d20eb978b7dcbe73f2112249477d15c8a85e54a79\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 49e3c8eef5e067cabd51a7c01384ce05ab8f4342f655559d8a689eb7b20e0106\nA = 18400c2cc3e06b99b4e39c77b9af5ff0e9c683f1708321afa4cd5b6988d13b36b1d9eb4379b7902d9ceb40c03f814b2b6a01b90509bbb4532f13ab1571c4d04a\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 35548c530745f440329325cc8a5fbd90c16a7f0788879a4869bc4d4f73acda0e\nA = 181a3c5ab02566e7166c4d6d2f2bd4a8ecc25991a98d270bde80cf4332766a7068b14240bf5f5dcd45e90ef252596da3eb05b11d68b2063f7b3a825742593ca9\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 1ab7046e6af061ade5f9719008fa4d989007e2a579a134a5b9f19ec410984096\nA = 1008a03e211fab0d45856377079bc96b0776c2d4c0175661f3493246cea2ab0a02a706c85314fb707ad9906bedb2cfd577d62092ae08ff21d7b949373ea954c7\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 2be9e3e7515960d90f115b89f60dedc173a73ce163b4036e85b7b6a76fd90852\nA = 392053a9f0100540a8e1a0c353e922068a84dad3a4a8e8962fbc0bee2b6a06e20d08ade16eb1409a16acfcac3db5c43c421505e07035ca308b15c4a6db0864c0\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 5b301bb93bdcf050183107e36258b53b4805918114ea1c2227b0911d5b4dc077\nA = 55e55e5f94dc3d7aabc921f6469d85fa2e1e92a87347c57afad5872306ae69f9fb99297d1e3e793dd9e8632244208154de5da7114fd876383bf1422f7ece024\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 2df9609e2f5a5156c3260461b2ee52eacdef00bd8b091479813143a6c5283f71\nA = 2099325b7f12fe77353ddf3f2b2c5ef77b49671b150af954cf84e9675e3ecde3e057084641a633d19533b4712ab49924c8b5c31d591abcc88291f51253fa2a7\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = dfab751710e9008e25e422d1199d6fbec4dc7fba35b4da9d225a746eb4126a0\nA = c006af53d4737fb293584df6ffe2e4cb3fd8dc77fb7c1f13b97bb9c249e3ee5fb9feff7488265b3093906c08a4946f142ac7b491937d24bfba6413366ce371d\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 26bc030008d6c60a09fb0e16093a649fcb40c6c21a8e2da2353ba4b07c4f85d5\nA = 1eaabcfad2ed349ac9356e6f4da0b301266ddde811cb0f817aba8f5c10fb8b8ba9d0ef2dd386b668f16eac296118fdb8cb7afe1b865648c81c2fa3cf21f2711b\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 35051b1482ec2578f3dc0000a422cb5111e43c37f1ac20b1844d3de2128c4556\nA = 315ff9de178681116f2a5fa78eebf4818e1d680435eacdfaf9d0e5c4fc01fc034b352c82fd52c81ca30d68864952dacc99d08269c9dd7ca99ccf22da98c3840\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = a5474252885cacf004c460a7793ff0b0a2187bb1a9ed700ae3470199faef71f\nA = 19856fc1351c4b02abf573bb2fc6ff92355fa369d62bb8f2260fa772fb1693f509a56cad661930abcac049dd70f4b16bed4a4c172e73e772504c9990ce7f92f\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 12daf4722387ecf47de1b0b6b110a062dc5ea2685bc9dbde66b8d15622985029\nA = fb8479787069116abc42abfd7dc0c24d2ad04fe0c04b42a6dff714af715d17e0fd77855f950f264542b06d48e8818de813ddb7975798b7debefcdaa5ff86beb\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 397996ed5c0ac6ad32e43c337e9de421b87774cc162bf7ac7bbedf4a9029255e\nA = 5aa04353321bd2de92481be740357f979da464b53aa39111fdbb734cf7af6b3857d1baa08d3a126a3dd34a2fbae2bf2b84e900686c1d31505b390185acef5fe5\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 2cf4b844a54ba359dc592ef1b49f43fcfeae84d1087edfefdd0b9174b43c0a3c\nA = 365a8650510bcfd8fa87432f167cf487234c215857403b9270b5eebeafa48cd6da47fd60dc311b94d1d72baad0447c31f0b212d755f46c256e16e5e015e6546e\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 9277c73043ff767c3fa606f0cd66b9d854a600c8c18287f191ce277758c3f31\nA = 62cec3901626d03e8df66299a87c54b1f7a55cafc99f0b6bba1b5d51a3d2b7d2171c9135a9d8a5346d436e0136b12e515e703e3cd84ecfe154eb94c6772a6d72\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 4189e5a90c1b1abdc1c7c05b3587e6f362e06f927b6cf5f0d271aab3d6f90765\nA = 336b8d0f9dac842c696bc020f49c6aa023842c16f2052eb02f17959006554ca0012042c80c72590f21c6bf5a3714c9cb552aa69730e33db93a56a909b273f39\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 36ccd38cb5a6bd8a73bca55936a2227c503664422c2296faf7e2b1c6a375a43a\nA = fecfd60a376befbe48d2c4f6d070d716d2f403cd5daefbce62b720df44deb605162c8f20f49fd7ec30d4f8e70d803d45b3a44b5d912baa3410d991165d7c507\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 198fc8569be172dc9b71023ed3d42d2ba94bae4099643f6517ab03f540527fdb\nA = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ec\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 21b7f74c30ded681d6138cf8e6fd798f32a049e94138e982f1845df3dc9e686f\nA = 9a30b791c1ba4f394b4e3dcd5837e474237f4fe8987b255c098a47b2c14c598ec69d2beae444dd4fe9c4ede8173d2b187677cc706a3c28f3b81627d8a5fb6fd\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186\nA = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f", - "2ab5ffc3e246b41c32f71e951f\n\n\n# NotModSquare tests.\n#\n# These test vectors are such that NotModSquare is not a square modulo P.\n\nNotModSquare = 03\nP = 07\n\nNotModSquare = 05\nP = 07\n\nNotModSquare = 06\nP = 07\n\nNotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# ModInv tests.\n#\n# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M.\n\nModInv = 00\nA = 00\nM = 01\n\nModInv = 00\nA = 01\nM = 01\n\nModInv = 00\nA = 02\nM = 01\n\nModInv = 00\nA = 03\nM = 01\n", + "-77f99bdf1eb09da6dcc\n\nProduct = -55afd796db7bce822a00073fc8926d3bd0c79772f036\nA = -a57da276998c548101f514e9f\nB = 848cdd6212b9bb3620a\n\nProduct = dc494b0d73e8ec07cd2bb6dd8191d2b4d48e7700cc34\nA = -a57da276998c548101f514e9f\nB = -154c39567bd8be5f6b4c\n\nProduct = 240e9301b4345b914ecd91a49a0e651524dcecb6fdc6c\nA = a57da276998c548101f514e9f\nB = 37c6e7ee89cf87674814\n\nProduct = -39002ecfd6d96661b336157ccef6536756ad2e9219be3\nA = a57da276998c548101f514e9f\nB = -582cdab09915a652203d\n\nProduct = -695f49fc891d53f396f0593efae3973082b76d4f9e944\nA = -a57da276998c548101f514e9f\nB = a30074dbce2246af043c\n\nProduct = bba2b7b45b97cb0d7fb30fed95089870742ad69e7aed7\nA = -a57da276998c548101f514e9f\nB = -1224195afc7b394ae8cc9\n\nProduct = 1910edc278515ab7d4cc09b496dc3c06c32c75bc7368af\nA = a57da276998c548101f514e9f\nB = 26c6701c39334169e7bf1\n\nProduct = -3670b7f9b661aba35ce50984d83173c84c8fa60e04d100\nA = a57da276998c548101f514e9f\nB = -5436e84b4a29858a68f00\n\nProduct = -7fa0d3e0082b37475342b7e22e5dbad7b8d4cb5d64f871\nA = -a57da276998c548101f514e9f\nB = c56e0f44fc63bca242eef\n\nProduct = da7fe3367ce640fa5941c033ac1874312f10ba5950da75\nA = -a57da276998c548101f514e9f\nB = -15200043166ff309f0426b\n\nProduct = 1871d72481f66b1d413100edd6b339cbbaa67b3b2b3cd57\nA = a57da276998c548101f514e9f\nB = 25d057879db26fa29a5e49\n\nProduct = -3cf1dd1e2df3456757d72f35353c3c7a659b2ef844ad857\nA = a57da276998c548101f514e9f\nB = -5e46be70de21949df67349\n\nProduct = -5e861cbe47aefab2a7ea59292aab1258932b9a322f66e63\nA = -a57da276998c548101f514e9f\nB = 9238670897685a6c9cbdbd\n\nProduct = f623344788efb857db55c924e95a437effa4dc8bb2bcd24\nA = -a57da276998c548101f514e9f\nB = -17cc0ec84c228225a7cf45c\n\nProduct = 15514c916b0ae7cde6add16c629d3e19ba52a101d75dff72\nA = a57da276998c548101f514e9f\nB = 20f9f925b3ed307edbb154e\n\nProduct = -460cf5b14f9d0b547c3084bf44207bf881745c409b08d07f\nA = a57da276998c548101f514e9f\nB = -6c5cbfd29f3dae1dce99221\n\nProduct = -5ddf7fb91d765af97dfda5333d8779e80837c2b51cfb4f43\nA = -a57da276998c548101f514e9f\nB = 9136aa79080defd1bcf90dd\n\nProduct = 12c1a0edfb6ab6a0caae2553fb3743827e1470a8954e0a3fd\nA = -a57da276998c548101f514e9f\nB = -1d03b512470dc3052779f3e3\n\nProduct = 28388a244214abf046488a8d95308d95f021eae4b994a5a52\nA = a57da276998c548101f514e9f\nB = 3e37dce784274962ff862e6e\n\nProduct = -4da476e76119deef291c0f56934a912a0877278a19a561ee0\nA = a57da276998c548101f514e9f\nB = -781b2f2dc40094a7f8fed520\n\nProduct = -5792496d33dd45e225f9dfca17419a04e075ffc0c90b37b82\nA = -a57da276998c548101f514e9f\nB = 87772a4fb582acafd3e4ef3e\n\nProduct = dd3a3506a7d748de16fb43d666928a87de0354d8e8a1bcaaa\nA = -a57da276998c548101f514e9f\nB = -1563841bf7851ff158a395716\n\nProduct = 24e8fb09a9ab0808ff643122479dea5ed41060c6c5b74e8752\nA = a57da276998c548101f514e9f\nB = 3918c30b5568318a58e9be16e\n\nProduct = -366c125f96b38b58d01c939c27c4100af3377eabb792b5491a\nA = a57da276998c548101f514e9f\nB = -542fb814f45924aa09a16f2a6\n\nProduct = 0\nA = 0\nB = 542fb814f45924aa09a16f2a6\n\nProduct = 0\nA = 542fb814f45924aa09a16f2a6\nB = 0\n\nProduct = 542fb814f45924aa09a16f2a6\nA = 1\nB = 542fb814f45924aa09a16f2a6\n\nProduct = 542fb814f45924aa09a16f2a6\nA = 542fb814f45924aa09a16f2a6\nB = 1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899f571f257fa81c36a868d80e7fa2bcbda68a72ca3e31db8892b94d073e006433dd7128b7bf677d2b411532e5662cdff66d657673d58e03d4a338bae1a5513296f91d4d2b5b680527a2e12318e422ec2b7f05ea4fd3ef4780576488211dad5733685a8f0e5d2ecda549a15eebb235495e70d26b194c994cf16d98d356218d08a34d1593d90bc0d3572df0e84bdb1705c6c5e64ea4895599bb21bf219abdd4329813ecc198e708cee199c22f749bdeb0c206690e8420883f6c0661e47b29969986a7a72996ef63234c31aa39b7be37995d2898063ef5c3b672c43afbc1a065dec2671ae87e17639cfcd3148145a8323e1e9dc4f9c9daf981dd6aba4e8be01344c2eda185b87\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899aa73af54a4e1825aa6714016da99d9e3d0c02eb139716db437705cd9efabf0123b0831689735f4e488f226e577d4688d30914dd50ed368939452af0a7a094c065c6718bd54f53a808585fc1728c3bd1e7c968d76c6dca32f95a8323bacad31cdd4aae544d4208262c40bcf726c2f26cf1e60341c3e1e0c8ed4542555b9bf00488680b737a245cc9b7817231f1f6f1e614cdf43ea281fb850ebbb9305b1aa441a45dfdaa1e98b9d79d9ca511be070bfa94d8cd3cc750607c93e1b451a14e32356bd48d77860b37fd2e714827e770a5648ce8579a00ba5cae034502a8b03ba754994d9e002130cfdee6bfdf078dc8f6767b927c964197664c8e32bd3d31bd461ce\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46feff82a92989bca577998c68ee619d9ea9972c6f139e97f5bdde635152830bedf302873508d2ed73badb82f9e32e1f4d12ea8c8b1059aa6d15f8e17d649bf41467903ab40d220d50570b5a263f637c0fcebc0ca29f8a81e2a01bf39bcb60cb9229dfd40618f706b941836bc5c291dec45ee9193e74d3a4cc5f73054ca56fd774a359f17a687268587393b76204a37cd48dcb09d3daed57a7e6d7d93a0ca3d6de8557fc4ddbfe9cb163fd10b7fe5f270dc57aa2fb88cdca2a3795015a17fd352d85fb688a38fa54883d0cab67aab08dbabd58d307c601f0f810014d78b101ff0bddb6d550b24807", + "82406a905b9201e70ef6c1cb9765e91c10c8f5d240c\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e3812764dd3ebb7489e6e66058ca6ccf9c007f8c049eda369b2889cc411bca78d4f5b0e3a9e80243e87e112072b01922b595afdef4dd562e58ce917f11e69c8fe050de54fdb2d607d05f09afd6dd140e9d195b91d85269610a1e5d5036e8c9fea2d4fa693d80ecdc819b201c0aed27dfe0b92b4b3b9ecabb3b9548f0d27dc917ffb14308c4f970863e163f375852fcd9fb115640dc40534f8f51a7b903599117dca6c80924fa9a1aeb43cf5a9a3f67ae818b484feed51d7ef60b3656720891b13a983c02c281c8a0954f13b7bfaca844d2cb66de5c11ff507e39cf774c7c93b38e296a44f04e5ecf2819b57943fb0509774ddbcfeb\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899c7bedb01951b0f4fdb2c0fb64ad74707fda20027f4cee25da9b59be288d404cbd348f27600b87015d28f03cdf411f0e8c22deb9de5b3e0094f7820d78d59c90017cbd426297f8a32fb4b55b09362cf7cfb5910085acb24dbf618752b8b74c7e87f9cac44cb3b7486c43aa9b19a64d40a74eaf1de8b5f168b43d5750236aef753278c11294efd1adaddb6addb846f45fa55d7391898e8ec1c82bcf0008d9850c4c096571e8872e975dc8af1ba01bfbe8c8c27dc30cdaddd198936e4496579741a3a20e1b8e17241fe4abe5e98794e469180b742b2e1904940381f703f512885bda0340fe74e997ab269be00a3ca29bb937db2e06d8054e26dc13a5014ba51b175\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d88997cc097fe3f7ace3ffb0fcee52b45551165bb02354b229788b59128489879b1a0373e9862a17692464a2dfc5d09185a0f1c67d2359ba70b52b03f21c7b24feb96e25e1a2dc7f4723952bf203979f7c9e38790f881e2b35006157825555d4c867fce9ea0a3cc6f1c94ee308a68e33f64f286247465ffe854033e9c64f5d79d6d66dcb38ad03535b20376bf4c3cf26e07ef445192ba2baf08bb5286695a61ff6b5dc7aa1832017198d61a324b8c244572157323c7bb3a2fee226133e1b0e0f2ff067cf71fc24bf38d0e172f459b0cdf0707c5bc586390faacf428bfdeb04e850ee0c35f6807eb6ca8d3a473dcc2239541115a8b0d33ea33295ff8c13b2a\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46fc245133c3335163cce37555d36c555182e6d9a754b9aa9305c070083d0fe806d2c5eda4a976f749d6ef40515c425e6531a7f4d11926e49907b7a8a938205e0d6fefaacb145200cbe3deec686476bcdc1f6bb3535147ecb00818f2cd666ac0dd497f0fbc087bf05c6425b7752a02e2a695655d4310f04943a6178946a74dbe4688bd1eb3f1a166aef37e39f3e1d36b6d6d422ec0db264cae8d44869f57a92952bd74a026dd7cfc672803905f029c723487d4123a7520688fc9c68b2384be32e881f64d0ed7ae555bf00e5799740dd8c6accc40f3fe573f194f4848bb05aea8a5509f2dd10fce023093f1ef20267244a990d7ffd462f4e85a4\nA = f33cad5d3876f0b6", + "0a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e353744d86d954c06f3b84ef271b184ac9957a5f88b08b606fa6aa97afc4983a62f1e74aa3f242e14a3f4cf5ea415d1437818663556a29d117ea7df1cf1ee32f70d6d5566e25d53f892c42d3f92e481b622455fce36e400de09e2d435099695354ceee249c793b76b3c544d70164381e0420ef8b85609502afff9130729ba7851e0775dc5d8c606ba614e7607625fbc38908c88fac43e29ff9b8728f5809e63f20289246b5128016478437550a833c60edb0df43dd9a47654f2e4ef308d4a18cea57ea4b0c6d08add07f2e7adc427cf591c29dbd1f975432922e3f2b71c75e4d2557efccf626be7a0d522b658d420ae321\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7be8e75d54e5ba9405f671d624eaf8d7a115d0479f6fb773b940525fd46b69bc43c815b6bb1798813ca95790bc68032f0b9e73fc964a9922507d8aac25f859745939b828ef5ed326b226b555e5088f13531be16272a89ad41ae82c940935b5d8fe75dc520a230cc279a887bce01bae0a79356f044af13c6f4a5e53c00b2d03cfcbb0f93b26202441a207ec91576410ac1750e257906d945bfe9204b73fc417600bd191edcf2e3eb79acbf4f84dda372405b5e98397abe85c1593543cd7a5b17cb90e299f422f0ce107d86b56474e435dbbcbb5314fb579cd68d54777aa2d0ff9b6b96de62b4676edea5b09589698ed829cad22a52aaec732b79edf6af\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7739032d1f8bb68307f4adc912f1d9b83797606874d4f2c669fe0b263565c4898a07701585237aa444234719adb869c17142126611a9cbd6e689fabb2847bb9dc5e2dc89694621a7179df1fe7371deb9bbdf5fea0b271d86bcde2796a65331c27365fb97fa3647435c47e5c854a95718fa49072cc239d046ca0ac2bf453beb31070370d59483adb42b9876776e43fccb663887f1a999f625eb8e9c4cdd0a89099c42cdff06be29ad9ea66a957002925c9425a83c3e74096ca31324134f5d4a2b7d3b8d7fd8d72192049f79c670874f65201c068c5aac2008a7df4e5eba02d88be8ec23683513a9cffe06671a7c2fa5da7a7aa571914caba1e\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a808857c1bdb914ae0fec75b02d527263093a9d9b8a42289ec74dc73e0e46568a9e8ee117659597434048308c9b66fa7a539694285b1238a13d1163fbac33db147e5431af1c7aca5b1a118db4f6650ec6340491ef7a2d203b53e43d536639f980eb6e92a37bffb2149c5eb45d6718a9496f0784370674c1d29732b944a3c3885b68f0fd2a121f556dc82d1b942e7aabba780f087b9df359d86e2055248c3aabc568e93bba67d3ccca2c4240c876506d63bb05aad6fc4c77dfafff1731a46c6711bc60c4d23976268928bc63e1d133add0633c737bb508c81fa1ff3b452b49b992ebac930432d555ab8c62ae17357b1186e80689672f5a9f472c\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be8", + "62f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6783ab6c7314a43e85a92955a5fbfbffcd31ef0913ba93563dab2b7f54d90fa21ca827ad15b5b1fb399a303f94837536b2813cb563f793fb780e91f8333a2de7bb9f10efdb652a504d6f242e7c15362d3a6eb6e3d1a5abb03023dfe964656979765a14fe8fc36af3d785030ce549b92a91dcb8e2aa13f5b89eb8449b31961a0f77117c8cac79af95ee69f6594e557af7bb017cd885027ff7c0cb1d2f99d1ed5eacb788f645c25150e737cf1184b546bb2d55f2014a18015ffe647580df6fe4d528ce983309baeac0347ae8739e2b1f6d1a83e12e4dbfea1cd81b11b8628837432ad1906c70323529b718c8c6e398e1dfa73\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f225bca564b7e6561b56e0edbb3a7f5934f382b916ab38423221d656357ce0e9bf1e9b04c0678b9c555e8365a0f977c95bd8dca1fb2ad2268193531ca36cbe7f40da8e1afe097e451dc2931b323ce731c03cc027a92ed8ae105c5e9c1bd385e238d989fadbf3aa54c097a8666df8a66b7e2d016e65a2a632603f2c84290ccd7346ada28dff79dd06c7f7989689aca4f494b977f984650f91327ab9936cb92675932440f135e54e4abeecf255d7061482b4c8d91769e02fc94b8acc43325d69541903c3ef7a7a8a5bd19bf886506d42bcf0efcb6197a8d178d6a60516a5aa771ae238a342dc61df8c18c6ba1ed952d4e0c3409c14639\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f2210cc134828c520a58df29ae28863a158a044937809d7d84d2940efbdddb448c64da5f1f31977e7865fd5529eac82fee3e804064a6315936295f8cb26f0de16a47373f5e8365939e280a57dacb508166a583a630c75730c2fe54971e70a35e224e7a1a21e3bd8f417a47c4796d34148cae15068e19eec637bed8f32846dc5aa7e8f50599e840903a8129206fc384e0b4085f9f1e7e3bf2fc67b62b02566ce73cb4b22d471cde35b4f0cccb74283cdded5748d62286f7ea5c184c1308d520ecc7c7f1535b1132708298bf94c0967bc8f8541bb2f2b3c81f11e50f1d8cba4ce3746ad5f85e6bacbefada657c9b386b991b2\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c36ad2daaf856508e861c7f68a2611a215a93e3a15f68f72bb80a4fe9f4cfb6c7f91639179342c633db0f70c9dd849b5b5767908b27e61b812659dcd1a0613433f2c0940be49010886bb384d4676bd523f9827c1a48c7649fbfa73e872a5160796813956979b0f3fd3af728dd48f8a7348090300e41b181c8acae08a3b3106b61f90b0421803e6eba0d68e9bc93d3b659fd6316ba2815cb4b3b6a74f1f3fd24b0c07f619d995ac2beada44188eb72d371a6894f90087eaabe148755409bbff60114bcfefbfe2182e6dc4218d0da75af80059bbb14e848c2e60790fb35bf1cb685cbb133b2baf3f2faefcc3f69e34102def4\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c0701452188", + "9172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef9518c8ddd2bbd782e5f8cb06be77fc8d0c29f12d4ce67bb2478369710d003f0cb6f40a1341a5a5f2509d2d189084ea4346a44368a54f44c2be4c7b90c4d22976a31985927d0379b2e5d715a7e67eb3228943a07325a29316c695867e8f4ff676e00ffca0a6dfe8fe24652aef9e7f12616e8a54e367b90942f543a01dc7c1b8000ff991228ae83fe0131cfc235ba12ab2bdb33bd4ab0ba1b356bdbc6da4a70eed9fbf2c704e14ed6230eb5478dac0b02f4def1d8c076d1c0c0e2c4cdadb248de4acf961cee51dc41e545bd5a605a0860fb343c28ebf3f8814a9d5a7e0f3e9c93e742db76bc5671258d1da7758b41efead5\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\n\n# Quotient tests.\n#\n# These test vectors satisfy Quotient = A / B, rounded towards zero, and\n# Remainder = A - B * Quotient.\n\nQuotient = 1\nRemainder = 0\nA = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c\nB = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c\n\nQuotient = -2\nRemainder = 1\nA = 107f0e6cebfe22ac11294a06fed2b994d01c9b3610d50bdd254adafd08c93be8ebdd1e85e1286fe9c9e682a90cbbd6351681b\nB = -83f873675ff11560894a5037f695cca680e4d9b086a85ee92a56d7e84649df475ee8f42f09437f4e4f34154865deb1a8b40d\n\nQuotient = -4\nRemainder = -2\nA = -3d8746ae2123c2d3f1d35910b42af1f86f5e81f8e98986cea20b2a1bdb8af6cf111f1258f112c837accdf4868463fe9eba536\nB = f61d1ab8848f0b4fc74d6442d0abc7e1bd7a07e3a6261b3a882ca86f6e2bdb3c447c4963c44b20deb337d21a118ffa7ae94d\n\nQuotient = 8\nRemainder = -3\nA = -5645d65662eaac73050de06f8f982a9b2ae680467712284be3e2b0e58ef4bf4d72b5be5e12ee1fd803b47f161759662ff5c4b\nB = -ac8bacacc5d558e60a1bc0df1f30553655cd008cee245097c7c561cb1de97e9ae56b7cbc25dc3fb00768fe2c2eb2cc5feb89\n\nQuotient = 10\nRemainder = 4\nA = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b4\nB = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b\n\nQuotient = -20\nRemainder = 5\nA = 12805392c55ffa0e27e85e15f2b339872793664e9ed3074cd2600aa52459a57197130d1ea46775ef43115c9413248cc7b34805\nB = -94029c962affd0713f42f0af9599cc393c9b3274f6983a669300552922cd2b8cb89868f5233baf7a188ae4a09924663d9a40\n\nQuotient = -40\nRemainder = -6\nA = -3579fc4d6083394c691b060cf9e20318fe17da0487337f76710bd11512578830ba94ac7b587a2d5ab7cb4afe611e349cdcfb86\nB = d5e7f135820ce531a46c1833e7880c63f85f68121ccdfdd9c42f4454495e20c2ea52b1ed61e8b56adf2d2bf98478d27373ee\n\nQuotient = 80\nRemainder = -7\nA = -74ebad4b39ebaaff82cd91082408c979527907c363d8f0f75db410523f8477c074c45ff85851b6275b1ebc5279029818e78d87\nB = -e9d75a9673d755ff059b2210481192f2a4f20f86c7b1e1eebb6820a47f08ef80e988bff0b0a36c4eb63d78a4f2053031cf1b\n\nQuotient = 100\nRemainder = 8\nA = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c08\nB = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c\n\nQuotient = -200\nRemainder = 9\nA = 1bf534da2f4365c96fc5dd4928e73ac24b157b5136ead90cf6596033ec387a2c14bca828000ae1725f3a5ace8ad67a8c07a0a09\nB = -dfa9a6d17a1b2e4b7e2eea494739d61258abda89b756c867b2cb019f61c3d160a5e5414000570b92f9d2d67456b3d4603d05\n\nQuotient = -400\nRemainder = -a\nA = -3a172cc9483774544311a1366659d9e61cc9fac7dc11c68e36aa991ef4d5e96becf5bac3e0967c904d926617ea11bb9551b980a\nB = e85cb32520ddd1510c4684d9996767987327eb1f70471a38daaa647bd357a5afb3d6eb0f8259f2413649985fa846ee5546e6\n\nQuotient = 800\nRemainder = -b\nA = -5ecff3a3e47fa615b6e3ce2dedfdeefbfe1d437c394631820968a9650b59dc3a2dd1c9a0b06537e4e5c408a59e580921503580b\nB = -bd9fe747c8ff4c2b6dc79c5bdbfbddf7fc3a86f8728c630412d152ca16b3b8745ba3934160ca6fc9cb88114b3cb01242a06b\n\nQuotient = 1000\nRemainder = c\nA = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae00c\nB = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae\n\nQuotient = -2000\nRemainder = d\nA = 163956bc32325f28f48d41d32bb08d2a9c4ccbb0d818368fb13941e82b27da21d04094f7e897ce79c2d0ff8470505f1ef63fc00d\nB = -b1cab5e19192f947a46a0e995d846954e2665d86c0c1b47d89ca0f41593ed10e8204a7bf44be73ce1687fc238282f8f7b1fe\n\nQuotient = -4000\nRemainder = -e\nA = -3763f8e43bd05e6ffeec6d509bbe6ff9a9022ced8cb191c9abaf5fd0e0b75a53e2ad581455e3af09e702a77b164ed3fb54ae000e\nB = dd8fe390ef4179bffbb1b5426ef9bfe6a408b3b632c64726aebd7f4382dd694f8ab56051578ebc279c0a9dec593b4fed52b8\n\nQuotient = 8000\nRemainder = -f\nA = -531dd44dfa9e79a5aec8fa7c84bd3b753c146770d22d2c14a6d2125f7ab95e9b320e84c31cf3e0d883e1295a220f2a546550800f\nB = -a63ba89bf53cf34b5d91f4f9097a76ea7828cee1a45a58294da424bef572bd36641d098639e7c1b107c252b4441e54a8caa1\n\nQuotient = 10000\nRemainder = 10\nA = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c20010\nB = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c2\n\nQuotient = -20000\nRemainder = 11\nA = 179d7ede3db0c105525286551331d5b9e1f97a7883f0c13cf250afe9765bb5aaa527af7945c19cdd4596565cbc8532a3cfa5c0011\nB = -bcebf6f1ed86082a929432a8998eadcf0fcbd3c41f8609e792857f4bb2ddad55293d7bca2e0ce6ea2cb2b2e5e429951e7d2e\n\nQuotient = -40000\nRemainder = -12\nA = -293dc443c294c6a6c53dd49e84f58305d59a432afb6c7ea2039cd02a513231239571ae07f29b5427e869b9faa485511ca45980012\nB = a4f7110f0a531a9b14f7527a13d60c1756690cabedb1fa880e7340a944c8c48e55c6b81fca6d509fa1a6e7ea921544729166\n\nQuotient = 80000\nRemainder = -13\nA = -5b637eb8aa51ef15a18d9b144031c9756527fc0fb96c84b6df03700e5079ae1b3e96940a2c1e07f3b47ad8a9b2b8ca99171a00013\nB = -b6c6fd7154a3de2b431b3628806392eaca4ff81f72d9096dbe06e01ca0f35c367d2d2814583c0fe768f5b153657195322e34\n\nQuotient = 100000\nRemainder = 14\nA = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c19400014\nB = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c194\n\nQuotient = -200000\nRemainder = 15\nA = 11c2a4509f419aa977c3d37fa446fcf21b4b3b9f983fbaddeba4f51c285ac4032200711a54cc6edf24297b1f3d46ad020131a00015\nB = -8e152284fa0cd54bbe1e9bfd2237e790da59dcfcc1fdd6ef5d27a8e142d62019100388d2a66376f9214bd8f9ea356810098d\n\nQuotient = -400000\nRemainder = -16\nA = -39e37ae0edd92b957e84682358039f5e432c42492a44f3de01cdf74d643760260f2837946608", + "663e12291e9b0695449c1153800016\nB = e78deb83b764ae55fa11a08d600e7d790cb10924a913cf780737dd3590dd80983ca0de51982198f848a47a6c1a551270454e\n\nQuotient = 800000\nRemainder = -17\nA = -72f725edd5a3dd6f20b5e9ca7da08a99f8ec9214c80588182c0d42e03bcff34b488b28c03cdf41813a6193c10672a8ee68f6000017\nB = -e5ee4bdbab47bade416bd394fb411533f1d92429900b1030581a85c0779fe6969116518079be830274c327820ce551dcd1ec\n\nQuotient = 1000000\nRemainder = 18\nA = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd000018\nB = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd\n\nQuotient = -2000000\nRemainder = 19\nA = 190790727c1514b4ef83a1c6aa07493c0af7087fbc8a675bfd9a1e97b8ef80ef684219d6c6f1a5fb5b919f105fd7717cdd5aa000019\nB = -c83c8393e0a8a5a77c1d0e35503a49e057b843fde4533adfecd0f4bdc77c077b4210ceb6378d2fdadc8cf882febb8be6ead5\n\nQuotient = -4000000\nRemainder = -1a\nA = -22d115ab02f8663d8c009960086a0275d301d358cd3b250bb9e7c16cc6ebed4a8fbe43bbced856d93be64a17377d95f5f9c8800001a\nB = 8b4456ac0be198f63002658021a809d74c074d6334ec942ee79f05b31bafb52a3ef90eef3b615b64ef99285cddf657d7e722\n\nQuotient = 8000000\nRemainder = -1b\nA = -41f2e708ba47494a13607223b08e6d99c0b4247436632961d873804e83446dc97139ffaef3e25969950bd4b5bb4ff73b1a25000001b\nB = -83e5ce11748e929426c0e447611cdb33816848e86cc652c3b0e7009d0688db92e273ff5de7c4b2d32a17a96b769fee76344a\n\nQuotient = 10000000\nRemainder = 1c\nA = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336000001c\nB = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336\n\nQuotient = -20000000\nRemainder = 1d\nA = 10888959278661bc36089519a215bda60f9ce24ff7c0ac1f543b6e652f94dbff1f32aa40cad2b4b4d676f16948551501c29f2000001d\nB = -84444ac93c330de1b044a8cd10aded307ce7127fbe0560faa1db73297ca6dff8f99552065695a5a6b3b78b4a42a8a80e14f9\n\nQuotient = -40000000\nRemainder = -1e\nA = -3ada453530a180fda58533ab8c62beb4f693a134f512e4d23e487dac3b575e5390c0a90992400e402bb47aac93d46ded55f54000001e\nB = eb6914d4c28603f69614ceae318afad3da4e84d3d44b9348f921f6b0ed5d794e4302a42649003900aed1eab24f51b7b557d5\n\nQuotient = 80000000\nRemainder = -1f\nA = -57879eb5d92d565daac3ac5173639bfe44b6ecc69ff770af57bd79c9b93841c5677042cb362b794f3d8b24b0d3b73ed1cba58000001f\nB = -af0f3d6bb25aacbb558758a2e6c737fc896dd98d3feee15eaf7af3937270838acee085966c56f29e7b164961a76e7da3974b\n\nQuotient = 100000000\nRemainder = 20\nA = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d00000020\nB = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d\n\nQuotient = -200000000\nRemainder = 21\nA = 1c267719338a4562e934bc57fabe6da86ca534a34244bd38c15032f01f47c2fd498c83f644b345c5c661ada0e586a096bb63000000021\nB = -e133b8c99c522b1749a5e2bfd5f36d436529a51a1225e9c60a819780fa3e17ea4c641fb2259a2e2e330d6d072c3504b5db18\n\nQuotient = -400000000\nRemainder = -22\nA = -250249f2185d4b428fa9534f03ef3cbed535bd31c56c0b273e6c3d35e0266f7777a6e59a99da5738b8e3af8ac60061d6716ac00000022\nB = 940927c861752d0a3ea54d3c0fbcf2fb54d6f4c715b02c9cf9b0f4d78099bdddde9b966a67695ce2e38ebe2b18018759c5ab\n\nQuotient = 800000000\nRemainder = -23\nA = -710b30c23c3c4e646ba90da33d2ce35af2ff181c40b02e3ffa607966730c6b6e274dd4c3c78e578e0b10f431f2d832274bf6800000023\nB = -e216618478789cc8d7521b467a59c6b5e5fe303881605c7ff4c0f2cce618d6dc4e9ba9878f1caf1c1621e863e5b0644e97ed\n\nQuotient = 1000000000\nRemainder = 24\nA = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719000000024\nB = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719\n\nQuotient = -2000000000\nRemainder = 25\nA = 1ed1b7d9e4cf3d44ee98ef69850e61a39f54cc407c6795c07c887374441fd9ec258c21193f8a8c55802fb8f8c579cf94cb0ce000000025\nB = -f68dbecf2679ea2774c77b4c28730d1cfaa66203e33cae03e4439ba220fecf612c6108c9fc5462ac017dc7c62bce7ca65867\n\nQuotient = -4000000000\nRemainder = -26\nA = -35d324ba37d2000f960ca1c9e1ab96e341a2ae6a5ea5cef014c73a39dde000d8ad9606b817ad67e4e4593cc5894d354854898000000026\nB = d74c92e8df48003e5832872786ae5b8d068ab9a97a973bc0531ce8e777800362b6581ae05eb59f939164f3162534d5215226\n\nQuotient = 8000000000\nRemainder = -27\nA = -7039477c3e0a6f415e25e9f9b1dab1edcd8a23f984e7e3bc149c206a3b756b1be001450af4049cd4535e4243d7032afcf6790000000027\nB = -e0728ef87c14de82bc4bd3f363b563db9b1447f309cfc778293840d476ead637c0028a15e80939a8a6bc8487ae0655f9ecf2\n\nQuotient = 10000000000\nRemainder = 28\nA = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba340000000028\nB = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba34\n\nQuotient = -20000000000\nRemainder = 29\nA = 14d27a16a9cf2fdbc85b88a604dd8f0e57b5b34a27089d75d805e05fbb367dfa61c085aa98b896e3e53b85ef774a3fa52417a0000000029\nB = -a693d0b54e797ede42dc453026ec7872bdad9a513844ebaec02f02fdd9b3efd30e042d54c5c4b71f29dc2f7bba51fd2920bd\n\nQuotient = -40000000000\nRemainder = -2a\nA = -3bd0119619fbb5b260c44050d61e6b1925a49713d754ceb06bafb1d730a93f199df654b153c40e75096ebbaf5a6ce3c801820000000002a\nB = ef40465867eed6c9831101435879ac6496925c4f5d533ac1aebec75cc2a4fc6677d952c54f1039d425baeebd69b38f200608\n\nQuotient = 80000000000\nRemainder = -2b\nA = -61a283fe41d965ee770704bb453f689cb82a81089422d6d904a91776a06d32857220286e6ef6327807b724062dda143b46890000000002b\nB = -c34507fc83b2cbdcee0e09768a7ed139705502112845adb209522eed40da650ae44050dcddec64f00f6e480c5bb428768d12\n\nQuotient = 100000000000\nRemainder = 2c\nA = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe10000000002c\nB = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe1\n\nQuotient = -200000000000\nRemainder = 2d\nA = 1eb7cfb197d19f56ad994eca52d1af6466fd09da07d68d63067602046b2d42d3063ef5eda6b58afd69fd92b0b727a0ecde1420000000002d\nB = -f5be7d8cbe8cfab56cca7652968d7b2337e84ed03eb46b1833b01023596a169831f7af6d35ac57eb4fec9585b93d0766f0a1\n\nQuotient = -400000000000\nRemainder = -2e\nA = -3ab858b3329e5bd0469118be52a867b2febbe2894d962cedeb3a5be1738db1cea106cd0710c9f6937348c2c63b109ae623d500000000002e\nB = eae162ccca796f411a4462f94aa19ecbfaef8a253658b3b7ace96f85ce36c73a841b341c4327da4dcd230b18ec426b988f54\n\nQuotient = 800000000000\nRemainder = -2f\nA = -6137bae6cf7573afcbb6fd5c066ba37648cba8db0ecafe9dbc66959b19deabf42f3083719a2268b7602bafa2140a1ee8ce7d80000000002f\nB = -c26f75cd9eeae75f976dfab80cd746ec919751b61d95fd3b78cd2b3633bd57e85e6106e33444d16ec0575f4428143dd19cfb\n\nQuotient = 1000000000000\nRemainder = 30\nA = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7000000000030\nB = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7\n\nQuotient = -2000000000000\nRemainder = 31\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -940693131e2ba7b2af531803794983337dd526f0d84d08d58723edf002a388d55c8502d88c2a2a6e78233a2a1b1c8d339a13\n\nQuotient = -611b743a0e2acb1043bb33de50a59eaa0405b37bf6b622075dd69291fe5b53305dbfcc377d1f3082319c153d0c1ffb3b3346\nRemainder = -16e346b6a4297\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 30c77f3380ccf\n\nQuotient = b9e34073d5e6e5b9e5d2d7250150f8ad86870faeb88d5aed5029fb25c176de216e2388e0f5d33f7c3b56102873eb40b06f2\nRemainder = -16ebc86eb88339\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -197b6f6ad5b75c\n\nQuotient = 141bc8752e846cd63743e6fce4a22efc3eb5f0ce46ba81b8f578c94c516288ec3610fc9923f45d4af2b94c0b0a20b48ed0a\nRemainder = 9bab19f12d81c3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = eb90162ecae18b\n\nQuotient = -381bd85c951e1dd775b0d7fab344aadf06b1b592c643b5852fa44aa55159eedf3b3e47fe0d9f399ad92da85ab2bfd18240\nRemainder = 1e4f817a2f52b71\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf04674", + "5436391a673426000000000031\nB = -546c109fa8a9d7b\n\nQuotient = -5e385a83b56830626cf8306acc232f955178080e86384bbcf92eec3a8961360223c4cfc1d8d118022972e61866cbfc46b\nRemainder = -292e149300fdd1ad\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3246242094394c8c\n\nQuotient = 9af0246f4b49316df43f61ae3795a764fe9b1d071ce227982ebda7988a7a7a98129c94a76635c6913cb15e4f75ea1608\nRemainder = -dd3b3e32ddc79cb9\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1e928618913898b2f\n\nQuotient = 1fe40099811c648aa4e84e4fbb8cbc19706774a11391fc03a9667d8dc72dd0b26c4a46d0bae56ba90fe4bfac1517d241\nRemainder = 16e021603d30dde2\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 948887c1634f4b08f\n\nQuotient = -3f4fa4c179dab02ad461bbea8f890292c934496db560f72878323a4463d77ae261363f4dc8f53eab145fcc3815d3253\nRemainder = 407ccb4f0b814dc5c5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4ad17434071e1ce664\n\nQuotient = -4d17d19f7f6861189a520776339a1e425876808111c303e391118714370111151ef4ad2e6e84250f59b0fe09ab3293\nRemainder = -36f745b0f421d16db7\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3d71635bcc25183cdde\n\nQuotient = b976d544af44e711351c6618106d3a002c42ebbe22fe939a2457d24e8dcc35c95dde5c7c77af6b4545344a198be82\nRemainder = -107334ab98e5099fec5f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -198a54e35fa0cfa328a9\n\nQuotient = 1307bb8e89aaff7466bc238d32672fbbde7be19d15423bcfa14f9a23fe85af9739b72807fd4bc420ad0b0fac37a42\nRemainder = 170ebe9b83d4c43b79ab\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = f8e923a8bbc0242eafe3\n\nQuotient = -3925a167c1c4d2fae265f277302b989466e309a7211e0b7173031cbbb91ab7fac8dfe43c9d832764e222e9d8581d\nRemainder = 4d404e93edb435dbd60af\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -52e36cee22274556059ea\n\nQuotient = -4d5a6ef346a872142b999ff9a5429198b3c2a97e968f55aa2c01583efe30e9687c57e2bca2372db4d3d443052b6\nRemainder = -3a2ea5f9d204dc31f21833\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3d3c79a115d9071b573d2d\n\nQuotient = a49dee54430f1737a04543d5f549efafab25f0f28f5e304f1bbca191f99521c2c4be1b9927bde19e1ec2060bb2\nRemainder = -17d02758f8fcadca911a95f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1cc65a75211f2826c9d0811\n\nQuotient = 1808ab7c0ccac2ff8f7cb61248bf4624fb60352a356fdd1408904f8c6fb0cc52b7642ec59183bcaf5dd89ca0ac\nRemainder = 5c95323f3b8861261dc31ed\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = c516e6e3fa6e3dc52cf5933\n\nQuotient = -437e04d7076794850aada0cb4ca7a1055df103e74e00766be6a2fdb2631bf294cdbf2695d0a2f8f9eb5587aa5\nRemainder = 1fc63797594c56160536faa9\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -462ee529b488d1db2b6c60e8\n\nQuotient = -5dde5497accc4575a412e7232ce75bdf7905936e09e382d5c9f133faf82a05ad9dcc94ad858aed34cc14c714\nRemainder = -15e79293d5e055f906381a899\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 32765b0a34c88864d39bedaae\n\nQuotient = 11ac52a9287472e1d3b8577b3d50c95076e190714796761322b3ce869d96b44387e190e824849ee345d0a22b\nRemainder = -a158ccc7c055d64e7df3fbcf0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -10c061a37f6cbd11bf0c327643\n\nQuotient = 1ff5cda1551867577c5ca72c86516a82fb8fc5f59ce967b73c6bcc1b85168389872c9a747ddf044d6dba174\nRemainder = 21e766a0020ba429b330a325d5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 9435cd2dc2a92c950bb9e69b83\n\nQuotient = -2719c892fa3f4dbc9951b2095056a16159adaf32dff902e20a800a0cc2e858ccae408f2161aae25d3e1f6d\nRemainder = cafbe9caa1f83fd0dd3d5a6881\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7924e4dcf8f96da61f54bf83870\n\nQuotient = -5080dc99dba295f4a2d9a474c2ddfa3b232a82fe629fe62177514988983eff8195b37d3fee3afa343b497\nRemainder = -94ae72f78982ac1ff83f300cfe8\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3ad70d4b6b9b5f5b2eb65da67e1f\n\nQuotient = e475eebcfc53d49ffad2e0c2a4ba48fe7ce02c42ff107e01ab3fe5b26eee45c83c4f58c181d77c259155\nRemainder = -c83ac7582a02b47ee734e0f24dc5\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -14bbcff5423a260b21895327b18bc\n\nQuotient = 201308a421b85291d23465d648ad2a8d6f3393efc16fb675a42ea7bbca635ddd8c2449b1b34e5db30a03\nRemainder = 8e07efb8ae4c9df39533042362081\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 93aebb72a81ba68e8881fd1a56a90\n\nQuotient = -2584cc534f88f091fe471c652ac66a695906a7cde1fc1cde9be3ee09026b690c1a899378ff31f6acb90\nRemainder = 794801d9d5770a60e312b99d6b9f91\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7e408caf387a0ce9bbf4309c80755a\n\nQuotient = -63f7bfc0fe5a5421bc0a19fa6c87713a72eeb2a33e5eadee8c2f32c20d14f403ab8bdc424b9e8e0c68\nRemainder = -24227c242afedee2473c1a66a5cc29\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2f622c665af7f8126eabfd90df8e9c5\n\nQuotient = e557e6d2180aeeee5d2cef453fbdf38e84cc148f4608ade8836045498be2d318520ffadcea6319432\nRemainder = -dd290149e0e159f9ba6bb9f5a4b003d\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -14a7623d1d9dfc177e913d3119d0d30a\n\nQuotient = 1651d852316d472b41ba0460566e43fabb9257861859ad0fb6ea5a6433a4164299e078f4d50c58afb\nRemainder = fb60aff5fdd2a2b794b0d973ac4d92a\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d439da27b5e70342aa5cb365ece15665\n\nQuotient = -3ae357761a8ff43d3b1bc53eb336260342a39d22f8fac44eeeac96c2f6de32580dd6a688faa9c515\nRemainder = 4fa6f7ee4faf2f6be99c5ce4b65cd642f\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -50700f9c0da59482165a47a3eda2bf07a\n\nQuotient = -543b4390e4e254226683aa0b83b2ca176ec27a373969fb88f766ac72adc9125ff83b2652e46afd3\nRemainder = -12ff398d9a7d9e97a7f63a0bb293c8fb0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 383c5a4f1767e83fc382ad4f1c7c2b7ddb\n\nQuotient = ecb72c14c59d49287fb6b2cacdf04619ee617d5f3f0f1b2890fd4e79746a4fbd848613cf5eb437\nRemainder = -1035512a2717a89062d48f1bfd213333ed0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1402b751a1e5f3fc46e22b43240d6ce9b27\n\nQuotient = 1e800ddc5d5126f322298383f32fd593623eb88a91b2d68c5d9f56e20c16ffe2cefabe873570ab\nRemainder = 72935d534bed5ba557b91ea023601f50b1d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 9b4df766c608ff3efe5ea1f65cc850fa73c\n\nQuotient = -2c2dc2378abceb983904cdf6728f361d279b4c821710ae785724a7251c43fe4f705f023afa7e2\nRemainder = 249f6433af4e8e224eb570fd438197af62f3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -6b382f812816c77d65c94c0c660b31a69b8f\n\nQuotient = -5f3ced1e42fbd3c6b2c6f", + "1e16953e0c1bb6efb4e49566f974a968f69a1a66a3d7558f5a802a8\nRemainder = -317a7fb1af65982fe4641fbb1e5837e6ea3e1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 31bc97372d17038fd842b72eaba2abb26df62\n\nQuotient = af3fef8111c449b9e0858e7e53e1d00b764232f7a077d75043249c387ece30af351c8a40335\nRemainder = -a1493bcbf57a8480461d62796aa8f8541ece4\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1b076b2f7b78b4a0f0e24ba3a05d6c697efab9\n\nQuotient = 196734cefb08f09cb32ffefc07da8d9545d3451d5a08736757184bad94c73be71311cf1e01c\nRemainder = 273e33521f4d74840a96b3fffe169f79d32855\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = ba7746f4400f812919a3dc86b00642e1487691\n\nQuotient = -3c5989cf33145057a9c8e904435d12939db519cc6b9ca1c0a11934399cb139a73613950f2f\nRemainder = 456ebf56c636d54e37709b9e799e83b7a08cb93\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4e7d4f389423f42e980eda55b4a6a45f6f4bdc2\n\nQuotient = -8432cf3338bce1d12586f83025aea50cff3864af3eb2103a36bbb0aba10b0ba4831641633\nRemainder = -4f62c678137df301c4bef216e6aa910104e76ff\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 23d4c57b5a8162aae8d937be12efbcfd7b96ec06\n\nQuotient = 9f94c4399eef16dfc65a1e015e0786c86470299865932c4d564b71c9b1551a9c0308af38\nRemainder = -168b74a6073b4a5b54fa14aacb5c3bb7897ed0fe1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1daecf01ec633610373b79e04c22cd7499012bc66\n\nQuotient = 1d5b838dce6c0324f157ad125adefde6e1045dce9ff97cf8d1d39b79bce02128e3433ffe\nRemainder = 3aa816216d55fc3c910a030fd10fbda1e12f2ac2d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = a1598a12a84e9cba42ea0e200e88d4599c9f615fe\n\nQuotient = -3edb182b53890ca8762f3039d2d71a8a27c36cc884d0879e0635e6326af0182bc47cad7\nRemainder = 4610b2b1305220bc0de584dd3f87d90109012a8077\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4b5c2f1ba3a82047c9de61d47cbf1bec86b6ef90d6\n\nQuotient = -7571ed4c509630886483f6ca0923859e644063acb38cfb338bf3a681fe449501262516\nRemainder = -21c579846594fc3e5efc53ab01576a7b32d69faf41f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 28550e1f7c6492f4cb682c37b105f92b049c13fc03b\n\nQuotient = 9ed8fb31327a110ef4377258681c5287de8ef9dbe62aa4fe84a7f2a94bb69607cbdb2\nRemainder = -1b7bb759dd0ebc346cbe216e56be8063f063490c17c5\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1dd1e61caed1efc07d21ce05d889de1ad65808cae026\n\nQuotient = 1aa716227d1ca6af68286062b2d6dafd7ade16abbd5d6fa4ada0365832fe18f73bf35\nRemainder = 32e714b0c4ecefb38735cb88cd5e07c21c81be858cae\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b1b959a7b3262d7f4dff488315903aeaffd982b726d7\n\nQuotient = -2a9979a530046939e0b43a25edfbea6775784eb5cf346a9fc3a2d22e1aad473cdada\nRemainder = 4edeb91a2472e80068b1883cf2cc45d68ff9bbed1756b\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -6f31bbe097587a68fdf01d0bf93830bd03a23920ccc0f\n\nQuotient = -566ff76814e1c7d31ad53bfb9f3c0607ef1f7d1cf9bdee6e1cfb78b3ad7018f8bbd\nRemainder = -1eac095d6d84021c33aa9b219d191bd0637f20b5920eed\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 36ccf5bdece624b4f54c729a8cde13325d8dd764f44894\n\nQuotient = aee4f377611179d8b6315811dd94639aaaee63e99bddcfa8eee297ce1dc04daf8e\nRemainder = -59cb3ba7efa1637c46b21795872e8deaff90f13402cfaf\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1b157ad838684b45065aa77ca3238a4d8c5427f719cdfb7\n\nQuotient = 1c72d32cb83cf4a9043d3bb5002f61b03e29c34e44a9fc5cc4d613726f5e618546\nRemainder = 7312d11fb5828c7f1a0060a5152a7644fc1e6a59de28d03\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = a681444c4d47d829f7b629b561ffaa0c3be1232346c907d\n\nQuotient = -2702afc4095a0396215e3ca36e2a59725f743b30de0dd8d4ec4d943fef6c37162\nRemainder = 223dd3080ede3a64744b14df8742cedd71388b0df99073bd\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -796c9ea38ccf516a2054a1e584c18b64b996c9679960585a\n\nQuotient = -805585c6a7badc933bced6f8373ffdfe9796e963d3fc90e85b1a22c38f842062\nRemainder = -a6ebff3f651644915d5c466cc2915d104f0f85a44e08fd6f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 24e8fb7a6a3057ddcafff92916c46f7e4038b98c3104ae831\n\nQuotient = 10383ff8feeb180d4fde925b534be97ec3d5f1f1dab5d8cd9ab5d8ea646cfcdf\nRemainder = -a7efdd0401c74a69cf74442fe3da907acf92e8edc51668828\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1240a71ed8d81e86fd9b16e1d64f438b35d6f8eff672494017\n\nQuotient = 195d95a520fd22317492117dc756ff97806c48c1aac67a41ae56fe503a60cec\nRemainder = 8b8692bee56f8a1ada9ffd8b3583eae33a0df9b73a7d8585f1\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = babe02063b61cb90634ac0493174073d2419e00728d46ad2b0\n\nQuotient = -37791adae674b866e4791c107a697363847dee4a58a37806391426ea48b8c9\nRemainder = 33986fc6a5f5c4f4e31458fc7de55e08a4e9320509d90299b93\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -5563bb852e7338c65aa21c516eecf47f498e5788c608ed46cae\n\nQuotient = -68a30494eceff55e4f54a556dd9b30025ccfa22c0952fd746adfd13d31d00\nRemainder = -1b511d0ab81d528d00a1058850bef48df2e9ae9357e779bb9231\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2d44e919fd27bb3fd2093062d11830c30fa77febafe0a2082cc6\n\nQuotient = bd30999592dbeabb8871b76aa04cc1c6c3794a83f0178c2ad505d8189485\nRemainder = -b0dbce286df5faccf0bdb40ca60f508d436f9410c5e49c3f1360\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1909930e2d16fc877c15895a3ec8b2125858bfa1c5a1b8776bedd\n\nQuotient = 2171694ef4a9d57b83b09357a511d4e11cecbab5e9387928b480d686a0e9\nRemainder = 29abc8898d5ef85f87323c2a6fa36ab6e1bdbcc0ca742b1a2347e\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 8da37bc9c7c9bdc62f49cadcd40e156e776b7f4c8f7ad543f463b\n\nQuotient = -267d470f32911150d9944e684c14e1834734b15475bee968748dd5f6502\nRemainder = 53a2ffef61709bd7143c4c876e021f20a99ba481f2b11abcd45da3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7b117ddccee97816c2ca2f1a612cc0d94ac67f5a79ed41744c8fc7\n\nQuotient = -5a21a3bdd3a3d4f1361a978706ba1cec409c296a5b3c369e91fc8317bb\nRemainder = -2cdc818f1e445fb3772d2a56833aefb2f5565a5fca80662e6fc1845\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 348dfba3c793f0018d7d3a70c4060c3148b4a3163ba60af9d6f8b04\n\nQuotient = b301b4050fdf4ede8f9c746b26d968110e1eb119ca42cd9c9bd8d4fab\nRemainder = -17993daf81711fe59204ec82e363d2b91971129af9206ff9506d3cb1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1a76328184b9bea8770c91cfccf8ab98e75b2224d666af58022aca80\n\nQuotient = 19c401336dd43c221a61264f8b91791d250e6c99c61850efe6d1e3532\nRemainder = 6c9e547a77c98eaba1b021777dbd98ea88f7fd37c95a2b182f2b9067\nA = 1280d26263c574f655e", + "a63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b7d7b1f95f4fe2f267af88b81af88fbdf603e54ab6de73ccd000c32d\n\nQuotient = -38a77853de88a8db14612884b515e3cd7c673175779d4ab71ba58f83\nRemainder = 51851549cfa00dbfae388cc3b46fd4824268e00e12fba288acceab339\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -539c0171f48e4160e5c308ee9e74f35d8b6d032e946dbcf748b1335a8\n\nQuotient = -79a7eab82e5b65f4f6734e8803fa7c30852ea3ae56e801c5dd11778\nRemainder = -f89592eedcbcc68d5df80663b3cdc638d9d779707d4ae5a552d97d009\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 26efac15401a945ffd37066bc5af23191292765164a0f1e4fd537fd64b\n\nQuotient = d33afb58753a21581c5b2351a74f3d220599ed56ebeacf1d43eeb2\nRemainder = -f699437f44af44b3ddc080f5b74f753d35f70baf3866040ba3c64b30f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -166cc6a3c60facfa0d8d318f26c6514c7eb9113f6b625c1de804ad379f9\n\nQuotient = 19e55bdaaa5a375c36e6869700f8677db563e5cf985be2a8d1b012\nRemainder = 7bccc3a653f29f3f45b52b8de2449c868c64d976666c01bff2dca03a8d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b6eae7a82b5dd1554795573cbf558d7cfed813eec270c326bf290adccc2\n\nQuotient = -297530094c3e4270ab5cf67e60fa5af6a32eb41b18b050fa6d46d\nRemainder = 62d8b502e172da7bce53fbb7c1ae376b6c21b3a3a47523aa0023406e353d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7241ae5f1aaee9340d437ad2dab94b70dd29fc6fff7fe31b100aa5001644\n\nQuotient = -640f3c38230962c6d6fca459afe0e46137525e8d62dd9b84da73\nRemainder = -16fcadd5155910764ecf0b4bd0afc3707e2ce49cedcbd5414f1c7d860e95c\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2f570d2da7a4e62097eb494ca43f7bde33e36525308dc864ffbaeb5d48f97\n\nQuotient = b3895ebba13c8f383ac0482be02e1f5518511420cb4513426bb\nRemainder = -21bc847fdfd48c7a4c36c778681ea20481081cbb7af6b281c8b8ebf2b2c3b\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1a6233954b3480af5f911a6bb8ad33967d5e0446c3e56f521e892c986b6b82\n\nQuotient = 243f3fbefbf842c79c5e96162fc42fe4f177a59d27681c54b3a\nRemainder = bbfaf15a90e744dc4a1caceda3cb339e5491e4507a1118613c5e9739f976b\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 82ae783b8a13e2e65d52dd3a6d6b057163347872f4d72245ff364dbf2421ff\n\nQuotient = -30f7cef2948c9ebed8fa3c5ea9a9bfa96ee4e9729c9b18e9d3\nRemainder = 1feb3fd887629cca60c664e385dddf538d9bf7fff2d34ca9e0e7614946d807f\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -60bba60d69093c0134fcb90aefdb9c190e7bf037ecc13dab3cc7915d7893046\n\nQuotient = -6b6f0183c1f598a68683ba7435c05d700d74681fe472669a1\nRemainder = -1f4d58f81a8c18523918d31791a00ea9aafbbb87792d90a5392273ec4e405da2\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2c17372a5128d7c403a3b94838072ecf9aff88d164764b12bfbf6261df957e2f\n\nQuotient = c4347fe42b2a7d9d5a650b72724369c5c1f59262a7be3fc2\nRemainder = -1103ec9c4a15373949cae4e34b7b42e242da41edbf5ad8362ce5e5426d3154a1b\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1824671758069b7660bad819f06c86fc76a9344ea38412058380363e5c5b4086b\n\nQuotient = 15e8c8d6847dfe974cefeef5fee93da9e58b74d640c6c413\nRemainder = 61dac240f2b39832903d5ecad9cfda5162bf8ebb0610545f259b75c3dc6ab8771\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d83386fb9682576cc70cf84520c53169e391b414f5421cddca6e257bd77753c40\n\nQuotient = -3572711bf994e6ad48535cc4d65ac323ef1ccff530b4337\nRemainder = b5899d4cb879e37022c539962959339d055900cca16153da09b54c658753cf50e\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -58a05faf5c61f85ac5a090b6bb045c851ea17332d9bfad4309ce2b7a79ad3cc575\n\nQuotient = -6931ebfc6e34305e5d7cba5284829d088d1ec0abdde508\nRemainder = -1b09eafde481064bab3a5c7fd895edceca40b1e62a9cf953eae1061dfbe00936391\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2d0769f392ca9ec629ef1bfbdf08cd8cc9219330ffe3c05343df792dd94b1147714\n\nQuotient = 9a4800f0cb2bfbe8d234410deb510103b7da30cbac7d9\nRemainder = -971e4a529e439a1b96b942001631027ff2fbe40b8939e224adb7f2ed30faff64d1c\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1eb3d7971125a036c3a67d9f5ce580a4ef4c469a492be53a55bafd2eafd4032b5b9d\n\nQuotient = 23116704b7a1a86cfa2ee5707ee46268634db5d50dc0f\nRemainder = 467c6b64c8121e4f250492191ea36a27119a0a6d19af519bf7ccdc2436c885c99d85\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 87134e98f73470e23a96c6a9139af3d4d21574de8aa9ea1d720df8940bcbda343694\n\nQuotient = -3b7f72ecf4f55c02366c52f38a827f5773b7cdebb9ba\nRemainder = 194b334b2046a66be3ddd7c6df01c88967fcb11e97b8206d000bcf6043c6e9ccb13f5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4f9d0341cadfb1f0bc38184d93503faa196fb8170f8ba2b5d3b512c09d39b7f79a5b6\n\nQuotient = -6db1d69019dd4cb26fd65d5b88a31bb6413b30278a1\nRemainder = -2042a060391e181882dc0c8d91c3b03c1ea35e2eff01babb3ae876ba1e57a505d44856\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2b2e8f445c0c3aaef0285945e4ca37a700310e003086f34d02c891b94b117f3d3032fb\n\nQuotient = c0e5b9a5853bb21b5e2e37f469764579d5cb2bf984\nRemainder = -154669d4bce7914cdc8d79f2b8d1faa43e8cc3b20fb0767e1c9a47c9e1daed4b665cfdd\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -188e619dbb719381e701363de874fe168529c10f30d3ff184e4356991fdec1649f72235\n\nQuotient = 180054f8c36833d44cab9dd61e6d89d28605c564af\nRemainder = 59192ec5c6fbd9773b8b7dd7d8ab1800dfecc8eb01c29997d15ad75b79575d9e26e1fc9\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = c55b5eb165c63ac2794bfac21980ebacadb93f1e059309fd2b855621572e8d9b3f29018\n\nQuotient = -31412e97045c19ec38951b0e3884c66d1d7479437\nRemainder = 56f1425227bfc6eb1ecda7bfae0e5cb59e92a2cc5306b28465c8739e40893dc5c1e94cbc\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -602b8c25ded1ab3877f58cb048c733649c7dcadf87b2652e35c4e5544d2306107ebff7b3\n\nQuotient = -8da1489ccf7203ecead94c67a5750884122b6e75\nRemainder = -15162026586a1e55dda72785f31c9e6140d166a1fd34c87a7d8c78f8d8f87bbdcf8f75b1e\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2171ee4a6f7f67d5a33d0a08c367184d70ffe39da28562655e75f6b66c866b1c2ac93e467\n\nQuotient = e635f8bdbf80e99723aa5718d3fade4e573be2c\nRemainder = -ffbd73bfe05f95bc2b135f12682288c620215eac3d6d56503d93a90e06f236e597d1df975\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -149375d478a096e724b84faf795c589ef0d772c4623f5be38da99006cd833dc5b28363faed\n\nQuotient = 20f76f5c6d0c8284764a10f6936c22bfba5f851\nRemainder = 82e3fb3f7252dd87b5370d26d9e8b9e98c7d333701f0ce8a05c337054c7aeb343d04d7e342\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 8faf8c0a3ef94ab1069394998e5412a7d84f44aff97edf63abc46d96f897172c38faa0b13f\n\nQuotient = -382586dfe93872abbe3a504fc62a8973913f96\nRemainder = 4d407323ef56093eea2f3993334215950f4e1a85ba18cdcd77d819d92b8b292c3ec", + "8edea425\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -545d81ed25602b158bc79aadf98a8f655fc399fb8652ae94333bf54c8c9ffaf8c6b3f2a9d52\n\nQuotient = -7d179efc493eaceaf46572a1f3a62bdfc4a38\nRemainder = -3de3d817a9cf7d529b5229a503e8ebbbd2c53215ac3c584c010947f780198dee16ffbf47791\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 25dddb00f65d6a1ba8caf7815a8063c5da656d775eae9e0108c68ce11dc925183810888dd04c\n\nQuotient = a9f7e5f235bae0e3e29393ac5c99d510b009\nRemainder = -150478b4a0df3eb20dcd1be8da283a00636c021c5c6337e7732aae9c4b49853b95f6d2475ea7\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1bde6cae7f5ced9006c0b1a61fb50982a433e4e2050aa486298f456556d8e909e96933e2ba3ba\n\nQuotient = 16de125df5936181981b4c2d0051a8b4d211\nRemainder = 29ac7c8a11f9beb9ad649257994216146b663bf4f237c561bf315d95778fcdb1010283475ebf1\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = cf24735a60ff5906410be5c4d98e3c9247919b57e404aeabc7eaefbf07bd64762bc61b96c9040\n\nQuotient = -268a52cd10ab4814268f66d9f44f71a98eb\nRemainder = 20293699f12fbfef2e391963866fc082a7884cd13b1c9bd8d5d203558feed2b889720be936451a\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7ae7d548212830013b7d653072c33f0dd54a6ebd8792bf75809d29a8c798dbc67c3edd99a69b85\n\nQuotient = -8f051067ccb82b6a3dffedd0ff2ee97c46\nRemainder = -100dac0d3bf5aacc5fade281c071eb2399560a65349566567ce1c0c34e43f175a575ed1eeeb3b07\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 211ebb5dc59a051fdfa3b18ac491971e863f2086cdc099672c1215af4ec877e29950efa4f487be7\n\nQuotient = 9b7ee4c499386f922432fcb1a453ee2ec\nRemainder = -f410122a74386d724cdd45b2e548645ac5ee4a44cbfecb82aad34ae470526674da44ebbf557bb75\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1e76750814dec1ecbb1af0fa2281ab3185e94e47fc16a77fed312f23f261ad7709ad7c9f85862c1d\n\nQuotient = 23efb26228d7bcf281cd45f54572e2b3a\nRemainder = 65bf2ef1c2f8e94d98060aa305f85e6cb869c74eabad99877010d30654aa2e578ef6aa3c5f1122e3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 83cfc25e90a61cf8686e3d5857b2f958674d478622c54cf8427275ca5e9312ed24e44ed4a1b5e413\n\nQuotient = -2cfcae0e922f2d884bfa0a3346dc9812\nRemainder = 14de2725b11a9c6784d9608c52770d29b9fbf824ecd4890bf28f3ec0dc6c52e4df9be540332b8882d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -694b057ff381badb37c7c15c81e74cbd6774e8d61c9e7d450811c36262ea834fc1287fa59708ee072\n\nQuotient = -4c0238ff3c18d4d58e543f020002802\nRemainder = -2ddef796c50817e82ea6f64a02a8c6b30ab40070ff5401c2d39ca14b9c4d99de33834bfe566a0c2efb\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3e51c9ab14f522b55e8f9d3ba995c0846a864dfa2d568ea211b0cac1463ce6a1da72d0a15746fdcc9b\n\nQuotient = d41f9102a7785ce64f76b7d7b870b0\nRemainder = -106eaafdd518c658bd371164ee43ccd915a01b513fc7d220900039ff840ba36450e16ce9987e08e7141\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -16549c5d57b531528dd4d781f03cf275b66cb94eba038b782b739c3ab30b8631c8706abac06004a942d\n\nQuotient = 1616b432b3277e774aad92b0cf544c\nRemainder = 2c89373720b834d718ff3df985ae47c3a7cde0e0309f682f5fd48dc97a1ff3d69fa0dcaa1245e956445\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d6721300e877a8145d05f4f3d8085697c2ca5f34a5357fed0bdb7169f83b6f8d855232eeea594846b79\n\nQuotient = -320fd6a7375a42a3961362ae196d1\nRemainder = 5336711bf81237ea3449f4e9f4e6358dc250f8ebd86082cab92a8079f2c8f835bc783082efb0ed7e3f66\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -5e9e8e1d446fdd314d487cac1226088696e33161d923acb67d3c75e87e428bdbc193e02f53200610fcdb\n\nQuotient = -4bd06daed3f30345d269f51e4381\nRemainder = -1f3513bdefa40662f0f50a04b418a833aa2f85522dc6c399298b1b147662ef2164ddbfb7247ba9511b8ec\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3e7ab7ffe5f63a6c1e109b95b83af470ff820cdedbb3c90c398ec42e44a45e1ca894870a7fa51f17ad5c5\n\nQuotient = d6fd01a0c5b55fbe36e58bbe77b\nRemainder = -c51af3e8b430870388357cb366ea888bd7b4ccde09ad3a1d2ee1426af060245c6d6b5980ae87fb66c4642\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -16086df3dd5e665f2631a294563c68931faa19ee67d6a2153d262940a648ae71bb3c1745daca5ea977331d\n\nQuotient = 18bd9a8f5678d28cefd955cf99d\nRemainder = e193f2fece67b7abe16373c3f84f18dfedcf654d951bf47585fccfaf67ee04f5037354d057c9f5eaa8eef\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = bf758acacd11f3f3e6665cd740517c9ab2384266f3c7ff9afd0888cdad2f6c9401c24d6c11fc3949aabbaa\n\nQuotient = -371239db55c79521206c9e60c0\nRemainder = 93773085af7582dd298b09d7098835787978d820289ea6850f27d0d77eecce8614785e32b228f46ca4b371\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -56033fd85be464301f10177b58d895fbb6df6154da5c2a2a7cfc3a24d83a96f5295fb17a08148a4e51dde91\n\nQuotient = 696d8e378d12221e2d970c53bf63a20ef381db8566701972c22fe067cdba99c57b68706a5c6e52f21bb3de861e49ed2141b3036f07d1fd0ee\nRemainder = 9f0e50ca76031b\nA = b2668f5fbcf4170820ed3fc9b12a61862acf8e3cb17175482efe23c5cfd3556e77634d407b6d1f98a73437a8d6066319a7a860afcab2338a1b1313037e30f4d9\nB = 1b1313037e30f4d9\n\nQuotient = babe271ea266bc7bc16d193097903037819f82366c7e9ff8f2cb14157b40433c6ee327038d5dcc44140b070d823befaefbee5e13419f6f17\nRemainder = 93d7c547a9ba0a4a\nA = 74b1a591f449377836f378e05d2902b29964df59c6926e5a9182cc09ce3111783cb7021a185340b4880d56635de268d6f3855c4d9997373b9ff8df899ee3b3f1\nB = 9ff8df899ee3b3f1\n\nQuotient = 890139fef28aa3b77814e1122b9c7f26e746ee3c507e6082b508fcbe380de83b06a01f735239c6847c30eae44749fc8c5e3bd97eb40ba297\nRemainder = 6c97aace900389d0\nA = 7e89adea82b4cb6feb41297b6dc8d948e72c3d5554a987900e7fae48cfb38fb5282b13d9a1f5793cf7cbf1ef551865041c3ffe0e287714a6ec7123556af55a48\nB = ec7123556af55a48\n\nQuotient = 1fdeead441e2d7a6ce3cce2389b2a22248ddca7970ae3f7e7d8453052fd08534ff7c46f6a4537fb6f28df6c5fc8a7d384336e679b74205315\nRemainder = 2903c7cc2651bfa8\nA = 9ca66de3d83f0a747fe986464522bde5e42aeac20e8ace1ea13fa6bc9514c58517479a4281d4128c6d775489b85dfd114ad184613f308f6c4ea484a22ab0ad1e\nB = 4ea484a22ab0ad1e\n\nQuotient = 12f16c8f9f898a08853982e2ac5a906d784c5ab8d74007ba3ab311e861d7c1ac115efe694cab7583f75a4a59ceff2887dab53b2f1022aa452\nRemainder = 4bdaf1f352e87aa5\nA = 6e6a97b358b591b78db43772378dc084a11836ddc9dd4607f263ce620714e8fdf6bf67387c163b6f2999f84270802b4bd5c0f0377e949fbd5d42fe145e66ffeb\nB = 5d42fe145e66ffeb\n\nQuotient = 14e0c06c8cff1f9f5dd8afb6fa6c340f0953a18ba7d2b26b22d8e7f946ef20fd5ac277ceb59cbd4ce3e8213803c3b5b0452ed449e22bf2c29\nRemainder = 55422f1caf4a9a00\nA = bc9c054ff568af73e301e0751bc1ee055e82826cdc53449f2d9f45feda2ba227bedd6df9b74fb58a85917d60b087bef04a156a571716e9bc908ae83784ee35c0\nB = 908ae83784ee35c0\n\nQuotient = a457ea94da3237c0dd15ee30e9c13e7b4ca1dc90fcd67951b873787206babaed837a3eb17e298d74cae92d1059636f9aefe11aef9ffa31053\nRemainder = 124768541b600598\nA = ea6dc82b1906c277526ed867fe8b0fbe32feecfb935dbab860aef59a7d72799fd4e952e70b4c9304c7b2a06af8badcd6cfa12d0b6c9db38d16d2c4a24099ca14\nB = 16d2c4a24099ca14\n\nQuotient = da0a37eece8972a0e2e8817c54e67c4d9f92373340488539d5051984bce0ae3300ef6ca9d0902daa4d485dec3b4db6c8b1ffd2c5d08b18ae\nRemainder = 1ba15c46023500b9\nA = 36ca8763e20e6ebf07a55cdfdd83892bef0bab68ac092093bfdac1a49c1da015541196a24249bb2262e70f7ed53e0fbae61f02ebac4b61f740548136ce50f243\nB = 40548136ce50", + "f243\n\nQuotient = 3d8c433daedfbf681b528f88d610204d33bbe74d0b13978c34a617ae94177e07a757519b5a8f1a93a73d0751c7b5b72b4bdf475a9708fecac\nRemainder = 4cdfd72349c6110\nA = e0dd7e73b2a64dc017da65992176e2535c43b6fc14f2f7b0a7d894d768bbc77507eac0112b2dc3ca83d70989a1b949ccf374be6a012d80a23a74bba39671fcd0\nB = 3a74bba39671fcd0\n\nQuotient = 39d084b444e39c32f2883e9968301151802da15141f65893f37b8b834eb01c074aa1e1a978c5c99732c87ae106bf8db09e1728c8bf2aae88\nRemainder = 2950443357cd7477\nA = 16df31dc290559c3b6a3d192cf15d825cfe79f8dbd5c9848eac7fa90eea5d87f8b430cccf9baab3e8e4dc33467a4234d8551ff25e33af175654686ff1368e96f\nB = 654686ff1368e96f\n\nQuotient = bbead8f70c8e61114f22d36e97861f16037efabe1347613e78c51d7f539065421a66c907faddaed13ad2a0f0b00f8fd594e917799cd937e5\nRemainder = 3013136f5f728b68\nA = ba5e688ab4f8ab5c25592bc4334b6dc2b7a06d491d0f919b716bf1cf109b62a30d9dd59dd4bdf870dd2687894edab303277a5f3e3a537cc8fde3ee3bb61767d6\nB = fde3ee3bb61767d6\n\nQuotient = 42aefe467ff2a5614efef1edce25a1acba9c476b3abbcd680140a3aecf8f51c1ebaab8912de217451bfaca2842c0bae717b8a030b6318c0\nRemainder = 1f130dd2ead0d35e\nA = 17bd50b5322c51ac883852ad2a4446c039dbc210ca3aa0313065fc88cce6819b324e93b036bd0c71be58586cd2b243d01a4a918c10ea0cc5b22f9d795df09de\nB = 5b22f9d795df09de\n\nQuotient = 13de73dcd72a3638fe2a907fd7f6574bbb228698fa60e4ecffb082911c5f09c74bb4f50564d3d4035d07eedea38b634a3e3acc26c8e9aeff8\nRemainder = acb8702f0113e0c4\nA = e0327b2e59236a3f91ccf960490cc69b2afc854de9299ad2edff9618f9fe24251886afc65f5c581a9bc86013f356d599e98b8b10f5236a51b48a6b29025983a4\nB = b48a6b29025983a4\n\nQuotient = 27d11481f00519b786eaee96220afd45bc51700f7366fb5e7da35bbc84891aac3d9d2b709dddae371a6b78439fef810c68eef586e1d68350d\nRemainder = 3d1890c5e1555d74\nA = f3504d5d96c9e27a1527725ced337f1cd0a183531642051e166507432c01e8d44c4e8918701c2a05eb8a9d7e26bf04993f9adeef2826ae4e61c602477f849121\nB = 61c602477f849121\n\nQuotient = 10bdeac209c67b023044186704735c7291423054bcddc24b731ad601b49372f4d5ce6e9d85002f8dddf0411efce943f81a5e42cee2d0c9fe5\nRemainder = a93a0c5bd51004e4\nA = fa29e37b0d0410d19fd180149b14f94ec2edccd347da65f6832850aa06a61b7b78c96faf64dcb347893c93c560b8043466419864a382c6f2ef1412873b2d8cbf\nB = ef1412873b2d8cbf\n\nQuotient = 1c9b6cffe44241292320c0660b89f2f77aaadc8d36e33f5ac3da0f12b3c114a156870a92079f7192d237f8bf49aeee6282531c929cc56d75\nRemainder = 1ce3e5eb13ac7958\nA = 144325a641463ed6bddfcbd73e50620a44c606d71fac38efb1c9d2747b4903f7b51fdedacfb66db022aea09b43c7c2ad7b851035165ebe59b552d4f7eee617b2\nB = b552d4f7eee617b2\n\nQuotient = 1b4ad18dc0e634053beb3cf840b53e35117ea06309ea8ca22e37123fd7e1d391c96c792e5125e322c27daa73301024080d73ba3491484b659\nRemainder = 3286bdce6dc3a828\nA = e3a2b90d3ef446f6bde30d3e726cf3e78212324054b40deb0b18fe00645568fb0a6234b6bded6240977373731bb30d1349e25cefd54b7a9985735e9b78002691\nB = 85735e9b78002691\n\nQuotient = 28f5e8da6733240cc2f18e3cf4d42a50d92816062af33a9e1871fa89bdb39a0d905c49faf51cc1c1378741bea34d25ac2c8e522881a6f6087\nRemainder = 135784870eb40c68\nA = 593206f9367b72f9cc59b3e37d2eb23b2061422859162ee53656899c2471017474f500c6e23efe1f6b1e57852cd4229329dc182ba01a257122d76a26aaf9b844\nB = 22d76a26aaf9b844\n\nQuotient = 1ab276448d16c533b6e90b5b5ca266e13ec27b5a58c80b7657df963ec2d1fe4eb1c1d24873eff6408bcb3d0cf97c31e85240eedf0efcc1e5a\nRemainder = 27b105741264f875\nA = d84fde3d851b52ed3b2a1268e9b765ec6c09c5768bba709b3b799802fadac30a6c3184185e6d57249b1c34619f3c9d2b90bc0c348b22537281a39fcadf738083\nB = 81a39fcadf738083\n\nQuotient = 84a87678485b3e60ee1cae3701ebdf0a29ee44115a492c34a0c8e84090e14070eb2ad0abfe2c339f26b5099327515104fe3d1c5546feea98ed\nRemainder = 95f7434941f9d8\nA = f79a0643bcd9c28cc22cc7b4178b3340e4685dd2672792516d6fc08567d2de2d3e25d43f100a58826edb146ac94acac4213bb09bdf8a258001ddd0ab110b89fe\nB = 1ddd0ab110b89fe\n\nQuotient = 516a2ac26e5b3afa502c7f3c6f15376f7a380e5842c229443343b5b74dc3de84db3ae99a0c57043e32a504ded19943c0310cababb3e92cf8\nRemainder = 327cf78eed336523\nA = 17c0d5814e1020d5d69674bdf6b9df193a16c0c8567a589d014e8eb7f6c9c36560791f7acbbbacee7c456eb51a4cdd7ca88011e9d8d9f2d64ab08ad74f7be5cb\nB = 4ab08ad74f7be5cb\n\nQuotient = f0da0beebcfaa716f494cf3fc81fe65117c90adde3b3942e8e66986fe8050fd5c9ebe1c88c5db04cea4c4c14779555d70cafb53870671f95\nRemainder = 3b2f844440d7be00\nA = ebba8c393c2a22b094d824ed95b4acf6875719fc165f73ee6d359e1134949169fdacbb42d5deb8cea96e11e3aac985635b5bcc6c02a6778cfa8e03d9ce6fc680\nB = fa8e03d9ce6fc680\n\nQuotient = 56527f07593774f0fa642241400985d0bb9b41d3dc9e025ca069130d93afc972d75e3fe0f798e127c3e1b4e925000459a3a5a83b15186e516\nRemainder = b620b7a3b752b78\nA = 5d6cad9e26267abb480b2b9ac5ea323bc4c3c53e0de8ce40c89c85accf0499aea5b11703a04296519047585ff12f8795f98da0546c20016a115100eddabfb468\nB = 115100eddabfb468\n\nQuotient = 294dca3b56ce9529aed2c132a9bd6c0c61de7a58ac50582f396b4fadcf7873b502bb869f801a9ab1f12384631cefee72b3e6050a7f69eba4\nRemainder = 53a0fcf5486c7a6f\nA = 24aa73803f270185d23310df2cf3ef67b18d7800bc41aad2ca13f372a27ef0a9217194f3f512e79f545a903895def195a5eb9a1a1b6b3f4de340e9da9b305d3b\nB = e340e9da9b305d3b\n\nQuotient = 16bf4dab1c29bd284c9b6649de65a4ee58f21d6a8b51627ca133fa817872b1a4a9956662db0aead5898ed0eda08511be7c47449638f2fab95d\nRemainder = e7751deb047d98\nA = 77b04d93272491322ed2fe651044e28cadb2ae7825f02b55aeb0f73b8b8a8b336802416fe08c718ab681581ac04d87116323f61f50bfd2180542fcd4a46dcff6\nB = 542fcd4a46dcff6\n\nQuotient = 388ae1c243bc9111e663c0c80495c36e8767bafe188b532b7ac84b5160d902af1b638aec6e4c66955d16bd8ce94ce6027a7bf95910f705ad0\nRemainder = 7c667ea307017c2\nA = 52f357e9a57722a867d8199242e100f06e8df810ee913d6992bfd9dc03ed78bcf44d692aaa7be806df0c9e0802851d7ae8405f76114e6322177907198f85cb62\nB = 177907198f85cb62\n\nQuotient = 33dc2fcceef7dce92e3a9df58566c6e28d03b58ff6ecbbb31e43936cda6380a56788285d37b5e8f11487afd78c39cb2150cc98d9d78a0c6cb\nRemainder = 429a380c9f8eeeba\nA = d99cf9a0bfc347c9631ae8c69defe1f1509c3ecaeeee5dbc61317bb73fa5cc6e704f64c865cf4d898f8a2f63214dbd511f61aa6e09856222432376698f8d2f67\nB = 432376698f8d2f67\n\nQuotient = 18ecac9e5539a014cffd8310ceb1170577cb23aa9cb3c523d57ad83069d1609ff743cd3c275b67097a038b85afcd7105ad21672f9ecbbc7df\nRemainder = 37924fea665f5c92\nA = f87aa8b6e62b09291e0e9b832ad71d8f85d60501a8d89d2638dccd4022e89bc4932c186a198557282527dfa86dfacc2f90fe0656695b61429f8220509f5106b9\nB = 9f8220509f5106b9\n\nQuotient = 37c0649a53c8cab91a7458702870bf64cb1de9fc1c6b9a3b92444119d368501b62d3a5138af72bdb7752eab8af6bf4e3bdb9e3beb1805b88\nRemainder = de179463e3e91ad\nA = 995c04c1f24c4efe88393bab7a7545e39193662d5db7c8e557d6c554ed4367f5af82c463d0ba6bc3148620481140add5677937989e03fb52c0323980d8841d5\nB = 2c0323980d8841d5\n\nQuotient = a6d193cfe7d8983768ff29908ee6e07fee99927a4bc4ef41d01f63f3b4a2e7029630b7d925d0979458cdaa903771286af672253cd99593b3\nRemainder = 6bf69921db298b3e\nA = 55c856daa8110599cc4fde0a44acbd69a68eb177e0438f7d843ba0fb74caab2a7e0c8a6f176f5555779e65c555e9157a16a1497edf36ccb583a458f0372a57c9\nB = 83a458f0372a57c9\n\nQuotient = 63f379bef9866b59f8bfd6bb0120a75dc03506b0034e7440764afc8ec14d8d735aa6f03a568ea98d0a74ab9bbe9c6e11b288467e5f79a2539\nRemainder = 11c077beb8667d88\nA = ff1fc3ea60fb37ff23e2f2f4e207a86e055cca41eebcc5bd6376904b51fb3d233cb04666fdc92be33239b5ee552870e45717890e35fdbe3728d6ff55d5662419\nB = 28d6ff55d5662419\n\nQuotient = 285ba8cdfbf00b112e496ce65cdba2271c82a273b3d30bed82ef2d360790c5deb97f3311bd5eb9876a61e33b3a37782d00c2d5ffbeec752ca\nRemainder = 1672a8aa119c3a1d\nA = d614352268930d301aa4046cd38e2eda4dcfcc52eac984943f2c863de5c4f8a44473a8ecebf12cb8f4da4722d305e5c9c3eddc0109d416e854df334dbfcfdd4b\nB = 54df334dbfcfdd4b\n\nQuotient = 358178128648fa9ea28dcfe68b4cecc7071e129e3ce4d113f5d1e387f7e5a412e9d2dfe5ff16d9987a544004d213ade9c134cc240eeb6871\nRemainder = 44c3fdb374bc0c30\nA = 18b973dd011969e29a1f4a5b8f118313f715c2e31dfebd9fe0957cf23cf36eded89c38637a8d3512bb23324ff2a3627d5b942300200c823d764b7a6c12d1c91b\nB = 764b7a6c12d1c91b\n\nQuotient = 19ea7212f6604d423b308fe3f2f4986f31aea9d6a117a3e207e38ce5bbd8d7a866285ac60433630de547fc84e364c451457fbf864a82c6613\nRemainder = 2718de2dd0796f08\nA = 83577f755a448d5586e19486b04de7836818223ea920465c4eee979a9ce5696ad8e2fd5253b5d5dcfdf355465e8c0819658ccc5580fd29b351169b54c62b779c\nB = 51169b54c62b779c\n\nQuotient = 13e0c5b9905770b60a6f978d1c983cbc84dccfaed0f4222f534df80c7d3d129f5e8f74f19581332a7f6d383915424c71db4ca19bde2591fcd\nRemainder = abf5f6c8ab6ed4f4\nA = e2bf43c91cdbb24", + "4790eb165cc13feafea36f5187cc9bf8aa8cf202042efd5441e3822a1164992da5be750aaac0bb11f09375bdfbd4a39e3b682c7ee6ab5f5f1\nB = b682c7ee6ab5f5f1\n\nQuotient = 3919f31521e87f90df3a4463d0c83fa31e3f569449009d307962d26f07d854e8d3f0badbf55311c206bf34e6227949327a93b1a5ada7a930\nRemainder = 6c3802d44dd4668f\nA = 2546880cc6f97fb379afbc4a2664115ba7909414f35a5bf88be2ed5187bd1a24afaf82eeceb0b438d4999ebf9b7ec752236669425bd3cce6a71d9ad67ff2ff5f\nB = a71d9ad67ff2ff5f\n\nQuotient = 121d5ad4115c2768b962e51d09f426d61624e0f203ac6c923289b4e7964e165b34f3dc1ff938a7cf37478d407de251c64db71d3ee629c1035\nRemainder = 660a35e1c1245910\nA = a36d3250c123697adbbbdf489e6cb40be57febaff654ca951c9fa0b396b1714c55ed6e05e468153ac443dabca29de9b43cc0cc4e62cdf24690593662c86fb5ac\nB = 90593662c86fb5ac\n\nQuotient = ad81debaa02f6e60da58b46e76ce041fc4da64138634ea7b3c165b8fbda027eb64b6b5339e70babbb83430d60383c2cfe22029e617fd03a7\nRemainder = 2e4aeafa2ad76832\nA = 8992cd131757ba5cbe54aa58be115723ea3438ddc782a4d1996980b7b312fa76e4483584df744b10340e5fc9e468690cef538920a732a8f0cafb4e30846cad1d\nB = cafb4e30846cad1d\n\nQuotient = 67a71b9ebaec91121a8cf6bc2932b6be01af7954eca69c5202d771c2c2d13683cdf90ec942a3445771ccfe484f947f078de825ea88b3c05a\nRemainder = 8395953f744cfb31\nA = 4f8ada84096198175174896167405b85cbc03fe0642f6b263a70f9a22f19ad6c9aef38da8ac036d409e6fd925023c95312cebe04eb653e0ec473dc8dfed98967\nB = c473dc8dfed98967\n\nQuotient = 9416326e2347a541b777a0fa1b0c35d8fe76c940d24c6f6806d6ae8ac1e280c16e480786478bda3f780ee92f3f3c361574efc2ed5ca98e26\nRemainder = b8ff45f31bdb58d8\nA = 902f5e48b96b9b1fd16c3b21292ed495987ddac4e1d92b2ab10378f2966c4399d6a41eef622a4991ccd1f647531dcd145de4ac99b3036779f9414ed2f4ba7e08\nB = f9414ed2f4ba7e08\n\nQuotient = 403c651b4e571e8301c4158fc185396554bf61d900708d2af5c2bdf495b3cb539b0b9b5acd0d71654b3aa68024961d5a7bc9e2788e6c822b6\nRemainder = 7856ec047cec8dc\nA = bdd6d846983fbf140173a26d2b709b9f31b4fee1eac9d25fdf0ef3523be0e6afb372acab470cfe1806b36d84017ec99302eb9eb5eb2862222f4916d8b6201d14\nB = 2f4916d8b6201d14\n\nQuotient = 1b6d967173f9777cb6194c8f69289b91da731456fe5a1515a49e4463cd906c84f97381cabdf9f358d97fad5d3cb140e3a3de397e7f9f683157\nRemainder = 83649246ade8bb4\nA = e3da80658acd53ada7c2dc57178e697f2907c5b0c64f4a87a794ca7521105a0568a32874207646df3768ee60964b7d1d2e29ea6bf7fbaa7e084eabd4ea553a72\nB = 84eabd4ea553a72\n\nQuotient = 27b8f1e49e404455cc68217a20766590e749507976a3a6de25a7cf2c32593aaabb04d84deba1ec6bbe048a2959ffd747243c396dc53c9c811\nRemainder = 3daa032278ce53d0\nA = ff3ead7c7b27f607d16f1ef4ffa91b6cc28301b9256cfcb0c22b6818371ce648ae8812dc50a86e4bdc0d0b1e5b0d55c6ba07b240886a6d5766cfb3ed0937a543\nB = 66cfb3ed0937a543\n\nQuotient = bf987f58700508356fb6274f64a9f78d455e4c436fc6fcc980ec0800287ab3789b91c29a8a72b16645ecfeec926b6f8242f3c7dc3adb40cd\nRemainder = c007da44faa80584\nA = 971aa67c9af10f70977f600e10f9278b8e66d2471956da38e5f4b3fedce9a5fc7ff42b800bb4a78314c70bb59394d0880383f5182b6c1960c9e5b47ef8e63be5\nB = c9e5b47ef8e63be5\n\nQuotient = 7332104442474715d7c4cdac15fc1731240f8b4dd0e6ff3284a15a62a8f9a071dedb87f2220efcc5839cb7e6933a8f65d767819db26e134dd\nRemainder = ef65a7789f54174\nA = bcea2ae4b1edfebf905a5820f0481b6c58d76a69df9dbe84764add3f49496a5d7005d645eaee3754e0ed105c13a114e6a0eae5cc4efab6aa1a3d3a0050fa86f5\nB = 1a3d3a0050fa86f5\n\nQuotient = 3f6182804a7ff12fe7ed3c8521b55564559b1a47a78e1fd56597b9470e7e0f6e7e48c58bc8841c9d118718ccd5e0c0bf9a08d8e244ae60da5\nRemainder = 398e30aff5bd284\nA = 2b877181a960c5e29ab1b2672ee22539256a82369e8f6cb5bcfb69e5e4a41f782e89b58fc0ef6ca336469ff929729f8492b44f12199f0e1c0afd12b2c999e787\nB = afd12b2c999e787\n\nQuotient = 1a80a681d2c42edbcbde552323dac3a1c03b43251a99b5549da6cb39ec6947daa0d574f0df68512984fa8e269b0b27a5576b3aaccb76ebc23\nRemainder = 378e44fdc7a5ec4c\nA = d37e62f44de27a1418f348139eac5ab9fcc1ada21ea6d7695273daf638b4d7eee6745f54b99a9678cf742d304736ee356f66d16d874f8cc67fae9be5dfd41a3a\nB = 7fae9be5dfd41a3a\n\nQuotient = ee982a63816d56758c29d284c19b9b984908cf0a9ae3f1f926e162a2cae4f88703aa477c5c14042247635c103494d11593c2c3839baf4d93\nRemainder = 39afe3275c01aae6\nA = 9a0b0476cd33861d2fc3137df292728e1f636f6fcba5105f384533723231a3104e7c77df46f7f34a4bdc63d5c67b418cafcf106b26ad020ea547d34edac1d3a5\nB = a547d34edac1d3a5\n\nQuotient = fb3f4a39a661e5c31228a6b7b4c27e6e52d1954e8ce262b98b61650efffd762cf2a1aec228bec5d5787683cad6b2e6e49a0de91c15c81874\nRemainder = 63e5ed36ff73a42\nA = 4453712f56467328401a69d4d749a0771732734a760a74094e50a62a030cb604e735bfe0bf0641754edff94ac0e0549e8c10941255f0f21f459e52a6cfe4d9ca\nB = 459e52a6cfe4d9ca\n\nQuotient = 7af60a7c0f995178be76c070cf49eee311e6d1e3afaf50c8c93ff200c1b3fe742b23259b4fc0b9ed0947be4fc9a6c212d86de9a0f7dbb5279\nRemainder = 19657d8ce516a138\nA = c9c92a31ad0f3cfb56a294c42a26eaecb77edf33ed40a7e6797927a0c996a7c0a701b484741163df388bb082e3daebf4e1b7a99002632d6f1a41c1d517238557\nB = 1a41c1d517238557\n\nQuotient = c890c55a8e2a3105b9bf9344a57a9b9fab5fa1fd57083d52431b695553bfbe7a44a9b6cd1f83958224f351f8511b14215d1648e88e938573\nRemainder = 1bab5b03c372daee\nA = 88341550e470016c7ab600b9f6cb410071a77f907a58cb6da4ce3e955d1e859534c2c1098fcfd91b9fa66926e51896733c36a824c3a20844add94e27f30ca651\nB = add94e27f30ca651\n\nQuotient = 34c240c42da400317f66f5151630493a2f200ee418d5ca3300cab10dfb429c2acd7280bf066fe19115f86db83d8f5b93cda714533b16abfdc\nRemainder = 18cd326996ccebc1\nA = 7e96d7b90ff09b114dd4393e9bdfb13d8ff517681126c566e18dd6369d87d248734d94bd02a1f19cca90be7642822b636369c51dee441a9d2663ec896e1d6c6d\nB = 2663ec896e1d6c6d\n\nQuotient = 10d18159e75efa8204e325e6be830b4ee8d2c07419e8276edeac6cc286488fc0c888300db3ebb5f935aa82654d3b932540f0093d1880e1d6d\nRemainder = fe9b6b8ba7c30f8\nA = 731aa6e2fb2ad1e1f80d7668c7b0642203af24af382abd207a5ffb588209e8b5caf953e9a96b478f39ec03a397d1433998e3c95e382d93376d80cf0c957788e6\nB = 6d80cf0c957788e6\n\nQuotient = 450d1f4a105ff8d1a3efbb12165ca98c67ae70404472e4862db479e03313b08783ecc42104780c9d57df0ddf19c5b4547ee9ba52ea82dd0c7\nRemainder = 169e15b4d5aa180a\nA = 902bcb1904b80183656dcbd51879e2982e2b46a547c9ae3119ffc12c6a003e4321b519289b7f22fad19d16480182d1d797c3045b2d29dcc12167f9ce5e233d89\nB = 2167f9ce5e233d89\n\nQuotient = a426f71cb3d75365cd076a6c35c10765bbc3f4bd317fb83a70083b0f7dc43a4e0b95508e60dc1dedb780e9b485f4f7a8870960de669b73af2\nRemainder = da381ae5c97a506\nA = bd59dcdefcbaecd9292c4c3685fb87d3a94c0f0ed01e43e63e1f36fb65d6c5eab3b584f3d1f76d31458c9f6b4c69869d96e943c61df102771274c5b4d821469a\nB = 1274c5b4d821469a\n\nQuotient = 26ccd4b7be090af22221729b0ca51a5e66435c2d33f8d88f94405f6c0123ccbbbbc8080cd8448a977946019ccbf5d267ac3f151ebe686720\nRemainder = c41f9e7bf20b376c\nA = 212dbeff03f14b5825f0d7cf8a7501db21b60581a01a26d522ee44e7fe69545cfcaaac64dbc76c7e3027ac39ddc2d80af6f3fca1824c6ff6dae90967d9ab48ec\nB = dae90967d9ab48ec\n\nQuotient = 801df28f4fd987b4e980760f4f2625276a2a7191d453095c82aa98a2253324ad2873abae70cd98c28ef3ce102fdd53469b9f01889f3ba8b0\nRemainder = 8e435da582e59809\nA = 48341b28138dd04807e522e341f74ac46b0449fa45f96d7fc586997c056a21eb3c399752a6a6c023509f042cf9e879f397a34af9aa2ec2e8904674f2ea3ff739\nB = 904674f2ea3ff739\n\nQuotient = d3857b72b70adff9b5dec3cbc63de7c90ccd7aab6595339b2de39bd6b9789045141d224aa4e6bf9a06e017aa3edd00e716a771b3f5b97771\nRemainder = 14135c686d2e9f70\nA = c1cea45dd46409d5e24fb7ed7d849dbb079247af2d312e01083754ed07f65f090e4dd50d23a973488702ef00936c5d78af603ec0fdf03dceea8f939c922b1e7f\nB = ea8f939c922b1e7f\n\nQuotient = abe20c90896e261e7d31bf40e7f3136d36b0b78006d12225a4dbef6aaf2062b609379eefe7e5af5bcec17126286f196f1330da8477096763\nRemainder = 230307c44cd55896\nA = 19a637e4f3051be0f7c4d35513bca4a91ca9b8082fe3c73899b70b6805a7aa0458512495cb6ee1ade55ecd5851be1dba96d65202f06bc7122633a0d905017545\nB = 2633a0d905017545\n\nQuotient = 5ed3765c4a777a903e182f7c9ce39d19c01460f389b904c3ce1d3525edf25ffe7dc0f4d9e24f0bc8b7e01bef19c83e74f17884bd7bfabb2c\nRemainder = 40f5346f8775e20\nA = 546578393e914be30581e24508a33f6560a5805dfb1c675d1ff1d6f5eaa7ee638b9e0265f543413e04e3f1f3b0895dec271c9897a48d9ce9e3d7df32c15b75a0\nB = e3d7df32c15b75a0\n\nQuotient = ed73a67932746985465fb0606fb0e81595514f1647c911c303d4d31eb0306e3b2aece07320f6fea57a7071d73150591ab2a82a7d53968a81\nRemainder = 2e495a881876da00\nA = 8976445bc318921f7e12c8d4e8e50596849a1503b5efb65e939c291de136597c05a1fd16137f0bbbd7197df943cd612118d1e55a50ee097c94331c1cfb1e941c\nB = 94331c1cfb1e941c\n\nQuotient = 5dce24b7a16d847b0c43cf365ea20bee96", + "79fa0e8732813e827cf6ef3c9bdb7fd8846b5689ce8b80a7dc0dd05721cb06d2700aeeb7ff04d6\nRemainder = d8ead1ae3126aded\nA = 59b99e5d028e6771d27004bc19830a5fcb347f7ae04c0ba7c49130bfb198c5b16821e425c979e6d2dddc14889ae58475bb52c6cdefecf2a8f4dd6e462bbc8f47\nB = f4dd6e462bbc8f47\n\nQuotient = 170e10b399a4c5fe354b536fe59d53602102f215d5107493680ab6e181f67d75ffd45bf49ffb23cf9269b856156b5ac6b1c5def4ab1abb18a\nRemainder = 57131776937c5df9\nA = aeb35966e2a616762768b7f63ce3aee5e81561080617bbabd7846b3ca03fafaaef83dd05b8d16cef40db0a56f3b0ef6eca5e236681cb57c8793dc0907d9aa30f\nB = 793dc0907d9aa30f\n\nQuotient = 1acdb88f047f9bf679c50ed67ba01dd24dca92103f8ea2677215b6142083b64f9fd2a365499dc8f2bc61e29fa176f7d76b55557fa58e34f9\nRemainder = 5065b726dc6b3758\nA = 15a6292c9fb66c6770a8dbc6fd431d2a4b57338581f78d0860fda90182cca563eb2272a79fb4f5a6fc72c90dc23e8a95713b65988b5b3f9bcec4f0466c1c47cb\nB = cec4f0466c1c47cb\n\nQuotient = add8127c0a27c961203ea0351aed5b3c75aa816e9c2684574e55f55c7140adcbf69d2cff843e5f53c157bd60b43c45c8b6658de72062fbba\nRemainder = 67f48d3584cf4fe5\nA = 4e8938c8cc46d34e3369c5d8536b18c963dbde56020678f77cebac5f8777e0afc62ca2ba4f533cf6cf7561bdce77b6f495bc1b05f1416d1173a6a288012c7c73\nB = 73a6a288012c7c73\n\nQuotient = 688ddf883a0bcc1ff9bd582119c2fea7c059e19aded8c048390a1d8fd7d769666987418bbe0d4cf4b67009a342958928769375c1c0d558acf\nRemainder = a5356d04b64ee12\nA = e0c9e32056977aeca72e229d83f0d320fbaf5cd8bf3e033289f46101c75ef59a854982f33bcbcfd200034e8ff439d669a03fa404e7dbfea822664967d67dd5f1\nB = 22664967d67dd5f1\n\nQuotient = 39d4d94587fd1445f31457c275fd6294fcb69ba155e7da3e6cfef38ed1272d6c95755bca49007ca62cc101b038d264876f18594b8fd4c329\nRemainder = a34980d5046e2ed0\nA = 2efcb12fb55c923f5c6ca7ae076765059e15d9e75240a6e5fc3db92de184143fab1934c7450c3a380a9851846c9f43d67bc199a314e82e72cffee795d695f82e\nB = cffee795d695f82e\n\nQuotient = 145ea82eff186b7db4b11fa1514674fb9d41c698efb33227eb1abbc4eb78bdb2a280c0c4c47adaf4e010a4336cbb5650becd1ef544e223e53\nRemainder = 36052bba2867f5f4\nA = f6a6c7e33fd4c664652d696c495df387b85b132cfdfe34bbd35759477b4a3c052f610df57e49e85720489e4bb8dc923696400a4a28dd000cc1bd491446a50b96\nB = c1bd491446a50b96\n\nQuotient = 35d0c9d870348b113868282aaba22b21ec87cf421519a23b288b150604729356f924090ba038d7400c0ccd4932836c65902b4d3c46a202a0\nRemainder = dc8c7d087bf24b0\nA = 22228c8a5966ebdec64007704a373b0596ae702d62e29e468653b21a890ace2f02c27f26b043f48495687ce8c2ca8092ead21aa250ce0f6ca26129615a2432b0\nB = a26129615a2432b0\n\nQuotient = 52fc995a486c4bfd17ed9722948e9ede1c4ac2fe80e6bd7482fc47944c4337a185a506a9ca473d49073e1b813ad742f19b13d57914888d5f\nRemainder = 75c703f654ad630a\nA = 3473041ae301dd2806da30dcf06b9c09600086d6873cf3ee9d5a0be638849afb56bce2664f797de4123f6f8fe3e12acd32e33a285bb7f493a1cc13a7108327f5\nB = a1cc13a7108327f5\n\nQuotient = 1744946730b2789977620f2e7439641125dd338d1b31fc50813b34dea70b83d209330bd17fd527db9a402ad9752c26b8823082ec9971f4ae65\nRemainder = 453a3d59303ec3c\nA = c0f592d83649bcafb7e2de1a8a71fa863c1f51b595bfa638c8fe30731c6fca36da975b6f19c657e3ca29efff6febfb311c003ec68189998c084afe4979b5bb19\nB = 84afe4979b5bb19\n\nQuotient = 468f3eece20aa9d6473f3c559760793e702758a3d9cc19d7817216392c7cc7c3968778cf2fe0c3f0c1424d7512cee19ac0717952f18aa287\nRemainder = 5904e71034e3a02\nA = 1f0c99a128c757d76ae6dfcd01012f0453c8f89b00476ec46321ecb872f99a48b4da29a4abffd0bbff2b727dfa182652ca85350b4ce100fb70a6a40ab6c41d95\nB = 70a6a40ab6c41d95\n\nQuotient = 12198913ef16c1cfc7c1be13f1cc5991a61ff74935e09f0c46d26456b7cf2825403b9851d07d27e0197c1fa2ac5e32e836979a184f14cd94a\nRemainder = 33431c3df719f946\nA = fbfbf5494a9c5384c7ae3df6c02a5e1f9f32dc31cd7f437832696bba164bae1a9d95daefb8bc08e0e8e637436fb747084460697b5ef5ac9ddec06757dbe61aea\nB = dec06757dbe61aea\n\nQuotient = 376c2f902566d83c21eb7c3aa3a6fa0482ed52c253f67f00d5b915d0183c2d9a2891c2ff837fcb426a4c990c48bda4f90e0bf69d13558696\nRemainder = 31540f5e05e8b4df\nA = 2527f8cafaf7e8319ca53104229199188ab1ca5fe592bde8ecf605e17ca6446414e06898a85e177d6985b5cc6d4eeabd6b222b5f44b4fc1baba050665c090b5d\nB = aba050665c090b5d\n\nQuotient = b8fdd5cd7b2d9295258bd99e2780921cb2ea70627a79088039fc3ab1c62bcfc6307e86db4a7803f18e5339f152063f9e41d370e97b1ba2f5\nRemainder = 4ed4f2d12e4f4ba0\nA = a25bd113c5a8c67ef65aa80f1512de43c9441fec0c41250048d29c406fbdae80912eb3970457d621c552e3af7ef2d6bc1b5448e7df5be724e0adf6f71df7eef8\nB = e0adf6f71df7eef8\n\nQuotient = 5421daac8cdeb6acc2b8b0dd85b592f255ee4fedb3a9e90f2a5bedfb0f9f033d7c562c96958346bcdda4664c67848b9d9fa7d3892bc4e9af\nRemainder = 7e5661558c345eea\nA = 490aef65c81b32f5df76dd58decdec3e3f73bc1fcbdb6aee0c93cd98725056153b572509e75d2cc4b042bbeb0a77d27fbca1e39efbc765adde41a7dfc5c3576d\nB = de41a7dfc5c3576d\n\nQuotient = 156a8a24e7804c5f576cd1757dba44cb4185bc13cb56603b54ee3b70fa35cd98db1992904d4f7d99a63b3a486e6fb31141a9d39cc0301f897\nRemainder = 29e9c1627537e5a4\nA = 5e4a10e772de8dd2c96acd714f7d3880ae8ab460095a01038f3aa9b8ac8165889403b42019a1e70e0e7f32e77fb388eae3579dbcb690729c4671868b0526aeca\nB = 4671868b0526aeca\n\nQuotient = 1b0eff2ff0aeb2c02ee3cc9e0bff808f4d616eb290293b13a6b58a84127972bb417d55e1d001a9720ec72562ef3ea688e64c4f32c7e26cc87\nRemainder = 664d57c57d4952e\nA = 806b8504abfbeec4d5923f83ddc071be88e11c4394168854448df96160b95adb1fd9c288852e2f3df3e36916ba5118815ca2e83a6a7d9e074bef9c961e2958e3\nB = 4bef9c961e2958e3\n\nQuotient = 2e363b13b0457a0e9effc2d7e297df78f35e5d24d0f8ad4525b573fb2f66f374871291ee8a8ee3d15a823b560156d474c678f79ee480bbe4\nRemainder = 5ba8f49e0ca36ab4\nA = 2e1bb261d98ec405dbb068daac5efeb0a51f08149181864e9dd6bf6cfcb617b76d8facaee2ef468807e0403bc550d58e8ad9e5cc0f094b02ff6d0277fe642f44\nB = ff6d0277fe642f44\n\nQuotient = 149a5b1a81b9e47ed36be76252055bb202dc25f8fe7beaa1ce59c279b32941cfbaf8fe4555867850b2fba43b10b74534db82398320f9786d25\nRemainder = 1ef621737e81780\nA = 63de892cf5df40c98de78c755c99e94e0e76cd5dc0b49b8856fe69dd0abcdc535bb1416f0d02b4eeb54e8a939cf7ad4edfb7de4dac87523e04d8ea8637e50920\nB = 4d8ea8637e50920\n\nQuotient = dea8a9211974758752d89965eeeb93cc616f88ce757ec2809f829cbb8d99b4ffdc3f0f643779fc5e0bb53b5273a5b15965f4a364863592f\nRemainder = 9ae7de3edb6c7edc\nA = acd5cebd069f7febc38c318867ba3a562bbf8ea9b19a6b33538ba107e49439f8ac6e880c6267c29b39141dbe2273d93062464de307efdb7c6b738c0bb282c3e\nB = c6b738c0bb282c3e\n\nQuotient = e9149b347cdea84d740be70060b239af000c4336ddf36fd5159083b795c4763588c87a959df0104212a04cc928baf60b0ea72e8cccc6d477\nRemainder = 3ef5c6ee67e6f5da\nA = 6ccf1b8b406e6a106160e73ac4122a04c0814ef5a47708a6776eb52002d52772d3fce3fc05398172bba191390aba925bb23aa1eee626410877822f27d1e3cb09\nB = 77822f27d1e3cb09\n\nQuotient = 1606c2fe44cd0b780ee474a9c7daf0b2bebf62db0ba8ef5a99fe22036019890a4c7dff73e678965bb0e2a6e61d00a74a1d33dc1106842115a\nRemainder = 7cf920ba2897f714\nA = ef9a3983f26237576311a871e4a3df0538593dd0cfda58ab90b889fdb35c700f7d158abafad127605057ca0532e846992c41ec06902ce58cae0c1fe238c726cc\nB = ae0c1fe238c726cc\n\nQuotient = 8ccf17de5068451fef1c2808c62e19997c7f920d5cc0fde1f5a247cc57c6d730df553cf33094b786597a343a0ce9e4bffef568247e904343\nRemainder = 2689c40a54df34bc\nA = 8435babd279b7a3833d01988c58005d4557f7689ea9b7168ef42ce2b31a1a3c32a982aff654f271a651085335496dd826ee4b3bc27f58920f05dc6676e51c662\nB = f05dc6676e51c662\n\nQuotient = a9e78c48c779140b1d15843089765ce9ece3855537ce88cad3eb7aa7bd6ec72df65adacba2bdf6c491066406bdc3dd3dd734a70e93eed958\nRemainder = 53da0b15ac079ccd\nA = 78550cb7b58b58d6878b615dfa25a5b90a1ff631740e631c7f8829962446903c686c810c46a1551b6c1f7a89ae898435bb8e36d1bae24a80b54edbf4bbc9af85\nB = b54edbf4bbc9af85\n\nQuotient = 1e3b41304ee07f6baf1ca061e0e28a3740991c6ca2749eba70d3ea1f9cba8adec45cb69a31cbff22784a9e056e884713c0812e8c7981e49328\nRemainder = 3d051148ec43a72\nA = 76b9453d315e7a9c592e1f2640f5b6b90a65e7f2ff8ac24b9b47e35abb76fa5d303be6d501b341a882bdd9d2a1c81a9280724673f87fbe9803ed5a2e7edaeec2\nB = 3ed5a2e7edaeec2\n\nQuotient = 1921410e1a538a71d33d9c5de95593fada116200c399fa7590ebc374282570477f5f4abdd5166784ccee9671a1a23b96378df62168049f6b8\nRemainder = 1a1f4aeb882d7546\nA = e4aa84f782a65d376b10e7789a7d56695885aae274db6cb37e0a34414397a57b4a5f76dced11376af5fd11d31828203e685861a6dea239789196fe73d0e46116\nB = 9196fe73d0e46116\n\nQuotient = ed2afbd2e63617a651911017d9d02224d521e99275ab642ad1a941827983b17ef0f2067b5405b20e8e97f2ae6099150a1989df94276aadee\nRemainder = 4578107045b9cb81\nA = b547cd987638ff7e3c30fec9b728bc10c3b8cf16e7040bfe0fe9a26e44d2898c4c4d28", + "ef525cde2b4007b2ffb3aa80fc4514a99b9aa2e112c3acc56b72ddbe9b\nB = c3acc56b72ddbe9b\n\nQuotient = 56181509251931afca3bb9dca21eedd6ed4226be67497d8d1bd0ec052af146993e7358f132e842f9b6c4934cf1b4501f5d6c5912e65c8d3ce\nRemainder = 1b9861df51429a6\nA = 32988a4e0769a5aca200f6f6f1498512e13b4904a9a311cd8a962fdd688de0c6e50b04f42cdd2cf8bf9b0a6922657f9ad195773e1250f85509672452618da9c2\nB = 9672452618da9c2\n\nQuotient = 1fa45bb973dd1d2df0002772afba55284a1e41f6aa4b0d1a6c6a4beb8ae00b52e88a9889037b8bfa9b7ee38036c57b713b48af156c3f9e8d8\nRemainder = 2525d52ecdec8814\nA = bda657ddeabe24c82c883e85822941bf64448b7cbb368468078101289b6fca36680b3884e35edc1fce5a5cdbdfc11359a1ba8ac0785c09ba5fe5cdbd30726df4\nB = 5fe5cdbd30726df4\n\nQuotient = 63e21f5568d07976aa81a2690b9e81b76fc3291cdeb010d1693d0e80191186815c7b2f83551a5f1b172640425d4733f06f4df1b2c8a7e6ed7\nRemainder = 14781a368471ecae\nA = 9f3dad0b3b56de15ac46cde1d79aba6a2f3b34d685cc810e9fa3f2d865bea4afb480d58653630319a258e9e8ded9be93cda3bc52b80a9359198221221724cc3b\nB = 198221221724cc3b\n\nQuotient = aae37878db016dd758003b85ef52acc7288b7b74c4723e3876a710baed4751d3be2ae49123b248f2b2c55a5be702c4428b1dba9b8a6ae8a9\nRemainder = 6c754d5c167e1228\nA = 4b93a98eb7b92cea0a4f5c2223e77abdfbd332b39f295b4ac40f71625d88e4add7e482adf3010082d8dd8854cf714a54fba0887de87946e97137cf7eabda038f\nB = 7137cf7eabda038f\n\nQuotient = 9881f551c4b7e67611f37df29e77cbe4e2d9fd5e17b7da3d013d6f3d4312e53dd26dfe3a2a12525cfef1ef81e6ebeeb7ef8fb4f918bf15ee\nRemainder = b14595005716bfe3\nA = 7737f8e7337160c14cfa8411236ca0354d8aeabf389b9fc4b14bb2ec3bb68286f3d82eb394dbd8062862b955e9fc8e86eb646317d1315d09c81ef51b30288cf1\nB = c81ef51b30288cf1\n\nQuotient = 4c8519d4d85ccf845fc5b8f31c27c60f0893ffda29ba86e8a3fd5fe67de5d29cb29362679abde996039b8febda2ecf71f6b9e1c1874361464\nRemainder = 10fae644af084f8a\nA = 900f7846e927760d9986894de6489e53cbbcdd59f7707917e7581422508f2ce79b77bd2c56d964a41e60baa927ca679faedcd9cd8102dde91e1f583ae834b092\nB = 1e1f583ae834b092\n\nQuotient = 16ef17b40bb73063f3cd0929cfe2405ca0ff2d3d426ac05f8a8dfadc85659105f7f728e113baab59247c4c7936ab975c08d6f1c72c12c532\nRemainder = baff11e6961c72e3\nA = 130b212cb6f3d854e4f17524953fd8592f5e59dfe92fc7d955e2899d1dde1ae4aa20d749caa349ca8d1bda7eeec2310532a7af54660e2a1fd4929335a1623bad\nB = d4929335a1623bad\n\nQuotient = 1cdd7ee2eff733b83beda5b862673177e2f2151ee0fd9ac0bf0ec5b7e05516f1d1b59ea754b0483d0e4bfb7668bb99117907a58a8ceb78028\nRemainder = 29e33e0c2a515780\nA = b0131ec2c1ffe9a523591a9453d2fc740bf885e7efc1a0158905da1e646745ef1bbf39b406564cb3da2f842bee307b36219bdee5991c969d6199279c25d4e380\nB = 6199279c25d4e380\n\nQuotient = 20bfcd06f9c54c537ae563e33dab31047aa30a6bc4e7eb0902bfbab3bbb7e65df442c46625c39e08c88310116348e9ebca2450ab463727f90\nRemainder = 11d8f2f6d4c1f55c\nA = cefafbaa2990eaa88184162ecb118d20e5999e5a8fdd25ae7f6248650ea74a8cfb92c58efecdd5d31eceb618f1596d7a6bfd31d092cf86da651f629975faf91c\nB = 651f629975faf91c\n\nQuotient = 37204c5735e4ba5e47e845d8b652cfc2b1dc715abf21ea0ecf5b1c6c8b9e596591fd7a7f41787be1a028c147a721ebb891b0abe3bd079b589\nRemainder = 1ee700ffb0ea02d8\nA = ce22d36b3cb913b32bd0e25cc14c7270d3f7b8e600a9b6732377f846adafd7fbd8a09d12fb7011f2283d988fc29aa25948dd4a0f24512b4a3bd460ee19887d35\nB = 3bd460ee19887d35\n\nQuotient = 191051194e4362bb201f5471d4bfaf92f79b6fbd119ca3dc1afffba334869ed9f8acd14fc42a2d8f616d652610a483ad90f5140e9a5ca4172\nRemainder = 74785b6874d8fa37\nA = f3c79f9a6af1c5bec72218d969620149afe8bf068cf7a7aceda977076665bb5a2c30729ac3aa976c9be379c6a5458f1501db8802652ef69d9b9f4f097027ddd9\nB = 9b9f4f097027ddd9\n\nQuotient = 6c46c17fdb03d192f75d636e1e2ab4e858d55f0f205cffd75550c4347726b5cfe036c6c901782cbe5a04f1985d9fd1dd39d747d25a6a7a88\nRemainder = 9a836be71a24e72e\nA = 4f6cf6e357b4985442a25b5c84e2cc0a5e685e2f5ff71ceba439b81f4123e16db2296dd4333fff23eea92bdbb812daf1d27c721412fa9847bbc9a0bf08879b1e\nB = bbc9a0bf08879b1e\n\nQuotient = -4984390f93e11c9a77880cfbe157dc41d43fe901c8895ac5091c5367a77370b16d42e8cc260058adf4d3fc8ee8cc6c0099804f4c319f15561b0a2b1caa7d703db82a726c9eab569c\nRemainder = -19374dcf21822188d720d6ec892bda2c084e8af84f38012da7029a3c3660c7e813fd4f7644ca80373575ff98ab6d743e939269c51bf62e04f\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 330af318ce0ffdaa92448777ed117de9c104e0f975651322c8e01b1c470f3cfb7a78b11f7daeea57614cec37d18b89155f19babeda0016171\n\nQuotient = 1a56f7d6c06a316a9a466319cbd558a99f06843782673a54775d859768a61933de3fc410068d00d5f6ab13fafc9228fd40ad41434501f8827bd7461441140eb6977f18d102d446\nRemainder = -3c3d566cd48a909292be2ce30f88ebb68e9122a3359f52d1d7b0189c467b829a9f226c0b64845715020dee12d179913ddb7f17da2db86d854bd\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -8e770450768d07ce20ff8f5f6af464b1ee5f1d0e8faaf927a19d3ff801f6089378133e822b8e63cf29c4c9ed721adfc91d3355a3c7bbde77bdd\n\nQuotient = 42131cf8f52a6a3f189697ce402a8c9439bf05cb3dc1cf8bc49dc2f07cef15b3bf0102c941b5b3bde6440abc6eacfbf77ea8da06ce932fffb226b33dedf001e9657464b0f06\nRemainder = 4cd483574fce075404dd22072abe61200fc455c15b382c7f2962ffd82c38ec1e2c60f71267cbc35fcf77fe1f9301d6b5f884f1c416304aa9f4d4b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 38caa64e74b29a7e9bbf341edbab112a730b17103831a9ecb70ef077e9660b2dd1fbf71d7f6bb4cdae2ed7cdbe9070ec9fde996c91b9bca5b83450\n\nQuotient = -11d6883fcd705ac97cae5bb7f8a2929d6f636f4f232ae9a4af9769183dfce9a9296fa0714c3f4fa1eea467a5c96a484a59d0cdd87496b9398e7a818daf89a58add3a39e80\nRemainder = a6b7984fd80d719ffe2e6eb756e4e3bd7ab51f6088e04ac8fecdc744b0385294dd23b5007910109abf40cfca814c10addcb5330e422b6f5eab6efa2b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d25d50f53c694cddd56aadda2654ae5888603b39cdbace93d19c117af5505750aa24e615f95446862bd693f5b444e2a876eb2cf49f6c7acd007eae02\n\nQuotient = -3fa898b02c621915f44b213ba4e80b8e85c7a2f4c78df2bda7d99494bbca3eb2d9354965d83e1c9001f10aad9b3f3ed837a630b329f5a4b28935158fbd9d291a120b08\nRemainder = -320d41a3875da2e83ea9a83947f5abb1a7026c84020e983381722bf7aa87d5987ab088cb2c37fc3781c82c81bef3263fec560023e236a747030618e9d2b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3af2721aad4b18db27842b5e539d8cada9dcd7ac4c5b885065dd2496a6f76fa73c8a51b239b5c068ea6feffda22d8ea806fb488ad5a94210264597edb40\n\nQuotient = 179307c3e14de14a744d082825ed723b996a4e15f156ac473960583138c43f4275b4436c50ef8f21a7b450a969819b81c15bc355fbc5fb55cdd8e124d931d142851a\nRemainder = -9c8eabd36a25e995c1811b79a2a0357f6aeef4477cac0ffdd130046cb2a647f928a34d91d9b489d394965719cd58604b957c693a93145328e5568d33d88a9\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9f2d3da1da77914df66bc889a40847a0d705d4648a11f282e09173d170e96d84b5a45092d995318fe7a954b54b88b784423402519a38bb521e84a4f6c5485\n\nQuotient = 6c0f316406afb4cc2aebe34f7948422de0b612a02dc47f4ae59419c579fc465ceae1980a3e524fdfdbdfad4862f168a9851664688c9ba01a8bc1ac156a6276643\nRemainder = bf52a2fb6493eac22fc8b334ccd8e8fa347620539d9189d535373f94503310a027c5423197c7279bb51ab8c459e27f548d57b55740320e80b753290d077aa7f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99", + "c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22b9e55639ad3ff4f071a49c8bba6bd9047e162fb31882421db8ec5ce46f28fbc35040bbc74ead5a948c47c43e9c7adc32fa52046b53f12b07b5224e0d8e93e4\n\nQuotient = -1008fcb6894d8c411905136fb3e05b38ec5d8df35db06379fc2d6d3e3579bcb34fa6e021b98b899d9d082c111b1a6ac8e50418fcd5968ade6aff8828d8e4777\nRemainder = 3d7dca387b00c677d855fc4af4d86d86331fe4309929039e828765f0937990bffa964d3ffc5d4f2f4b8bea978329e7cedb847c7cc341ee52217f903ddcf9446ce4\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -ea045323f406bd7ce25b3ab4993b5f6dd92ca80e3a02607a862deb13470ccef229fad67ae958cd87fecf4f08d9609595077d0d1360d9fe48c4566e237aa877e7b1\n\nQuotient = -42a50301031962754ebf9c4b1e125e6df3dd40ffbe09c044b1cf4b62ffb4f92d298b05933a450bcef65e86398da80740a610ba45928000a5c12d26e9f6a4\nRemainder = -c5485b82cfefb3f980e0fc7c6cd89b1345a8fb942299bdc36ed4ff8916016315a0da84ca0ee2824dce3c7e5ed49d517c45173c9c8e30b224940af6cf828c73db8db7\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 384e523d5a687bd1a90101e43334894b6a27e8c6809a8bf5bffabc34d558a8309997dd6f2a3b7c1a63100dcc0b6647b444ef7e5aa4a9c52c7caba1ebd096c3fae6f95\n\nQuotient = 1054439945ccb5bc5461fed04e364c7a36d5dd2c0428872676debe07654b2ce31e435a90c81f2bac1032143acb0c49ad101398feee8426bf270bdc0229\nRemainder = -7bf919e14b2559ab82b3c1bf428d083a4c851a7a1fea44718377e9e945caa5cf48e0b1ad727e251bbb330292402a75ecd96a56db4ad07146533a3ab5a717d0a25a3a7c9\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e5cd83a644ec86b94f5e33d4dc307a2f14ee8653288145dabb2b5f894560c164470197fb9e37749656f47df343c245258627aeea17965fea10a57336bdc6b4a47443492\n\nQuotient = 62675274798218da426a54ed7158f8f737b7b3c328a9c351371f0cf61f41712f9b28741f187eb635ce45866762fb5fc5051776151d202e2556c5845\nRemainder = 1aeb5d1fde3c259917e430e6790b00484d0d9508391ba6ebab0f6299190d4b34f5f7d8ea2174974471a1e28ee2c15e05da645db971f699d5d0e80569b7eba7908ae579f5ed\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2622350611b486e6be7a7c1c073c230d604d782c2696038a3233ebcc3f01c6a711969094e47f49e294f2c5bcd04fb1b7c0934f19bf6e7aa519a8d4ec2c172ac59cc1a57b26\n\nQuotient = -12970cdd96b92c37787971cd8dd166999ff241be881eb9543ff29165a9c1a3beeb38b1910a5724ffe2b73ab95ac1ca88d3989aa531374d4ec6122\nRemainder = 627455cb555398150e5b4c1c53ee16dac8d80d9616ed1ef40031424287f8028a9cad1a10bdd8430f6f65368cfd00390c8d4355aa5ecdbd1ff0266a1ade235f33cb5309446961\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c9dac93cfb7abaa3fcde359e09a92ab0b5c06359bc09ae9bade3c6783064dba90b233b4c8d5c6236a13ef96c7a223e37bbdd931eae61e845e5a10088f75b3ff5f1158e833b15\n\nQuotient = -6742b3871dece5986d4e219bf5f43c101da8896f247521fa286fde696e0b71ffeb3b6a3e4f33710c9ab150b7a1f747cee76839c5e7f2509f62\nRemainder = -203b2d6eec9d485f7b439fe9d4c640bb31170af38418faf4daad577c30e44ca06efda55ceea4fbd959b3809fa2002b6e2cb891decb09334ed89ac66ff05502036b2155ff62f8aeb\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2457088096865cd052e9cd9349c6e5e34e46c89d6e860a36f8e2a0bb1e5d983e07d05e6f6b31edc67e4793cb4d40979c029c80a13e654b66c8acf6b894f615a3ac800bbd09ce020\n\nQuotient = 15eafc416460d757d0abbda8d094eb535262a71dd033c25e704a6df54265b6123247e5625da476e0c220ba88582a1ed94265135bf8bf1fb1\nRemainder = -64ccd9a0ae0b0abcb5507d51b2e6c8e52e67907474605c439796febda06eabd8a3185fdfc0bd088cc49fdf564b5b45890b07269c15b1aa2f993cd9872b97aa6cc37dea2f03444b3ed\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -ab34d3906d8a2b806b22c73d44948d703c1e05a9337f75cb0b5df5205c5e2d23f8a92d8381372f9398c9ac2f7b9302b83e48b26512ccd0b06e6b8ef1b930ec2678d71e2eddbf7349e\n\nQuotient = 3b22916d9fe3145fcc3b8872bebf5aee4e14235f618e0aed09199852c6bed80df39256d8407d334c06f4479f230913370b7d451fad99d\nRemainder = 1b02a7b97f9ac1f6306aa00fff0e59f55fce463ffdc640364a950df29474e08b67cdfcec0628e973d42fa1e4f98e988ec4c47e4915651a1731b71d5e36a10a0d1b3420427dbb79ba7d52\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3f74cafe9ab0c1b307cd7571fd442665fa3205fb2f45b3811b92d1d38b096a2025b8170663a29c52ca84da102e62048e583fba96a594c0b23952fec587814857c25221ff2cd0533cba6d\n\nQuotient = -12ffa4b6fc369404968911c17358012b993c18c2ff34122e06f450d3d441926b5f5638b40efb012d76d8bcd3c0012d0a0ce5d55c596\nRemainder = 64548684fd5f6c816bd296234740a4eed772570bd4a48852462f9cddf14f1350ce7c7c6a58aee8f66ad7df87927458db09e3af08eb5376de08444f35e5171cfa0992fb27f70b81574f6e8f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c58383afca9e1c480ee75d3cb6b0b99ea42e827d39fc96bab6b0dddc97e3eaaaec02a74847f9f7d49937f5ade3580bfcd491990737d172d4079437067251ab403c36a9826e974b113e2d2a\n\nQuotient = -4964410c2b038573107b0151b36177cdd62495e0dbef536b59c8aacb8836bb45e7bb014e5022360621e8e82a273d0d462b8eb6fc\nRemainder = -1250c42f8c9b129a5c477be446b86356edd1b19409d362c3a5fb5d59c30f1c3fdc1424a88a0d6ce20bae885905d98c8a5a6495931f73edf4c60112ed78834e3bff6de3ed54c867fbf16a1cd53\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33212ef4a8e80daf1049ac6f639f8e1990142ac32f7ebc97675ec90f8eb1a2814dfdd295ae67317253d0187ad33f3932a3a7efb056d0a3c87d28e64e23e9f1de751ee6f0f61c6f39d08d72f0a\n\nQuotient = 17f77efddeed52ef2e423bc2c10d2ae15c97384b766f4108474964c2a44789e61249103d9f5fe00b4d612772dc6ea12a42e395\nRemainder = -1ec95323b7b95169d5ec0667f3cbf683e98c15dd0fe44df4ed9de9586e43f1f69337e41a6d11d889452665dc0b03cf8d9ef2effe0b350eeb9f6468751b8a2c42608ba2a33192b770cb62381a966\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9c91fdf2dd1827ed103a102db254630c278bf8b47bb12a342a92f081acbdd8ae5f5476ae194e24b187011ac25b19fd09e6e690777f9d3efb6b3a32c8f5905e1478a27fe4b1adf17a70abb4e7571\n\nQuotient = 4f5dec525ffc737094f40d27446ca0be5b7a2aff02d51d99609165c4cea0dbbc1d92bc0a8680782b616c149bbef7f5ca912\nRemainder = 1bc84ce56a9a0c74962681c02ac927051c81f3824d9f3f0f91465df333ecdb449473d9c26ae3abb9509add5795e89ba5eba6ec7c89b114c86e6991ca0c185b34d6e66925a14fd82809dbc", + "4936d273\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f47be01e6dc6a86097676fbd472c2af0c83a2f743fcaa885e44fda7e9f350e9fb7a8cd07fda59ccb7963f1e95e6a1236f5f94939decdc85afc0e523c711b24641c844cd3113c17fe35ca988ba407c\n\nQuotient = -163cafed5bcfdeda88555f30bd4cc2da2cefe2bcec9a7c19c36ccd04a45121a5a0dc28d0bf6ab7fa4b78933c47a5d5286\nRemainder = 93f856077f5b2907cefcddc4d767ffeb0acb7af64bb9dd8a15dcfdda6c244c24fb8404ff9ea2fe1dc337faa05930d33cac4f61e171d0236e222374cb3da76396ae1329a407fb4ac652fcbdc568d0fafb\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -a8bfcac452a5e48fee9132b73bc2fef771450143ab80aabd8690ce54c9b52c2b5a669076a7a35fa6d926268077bec6d90b722b5d074f28ce3843fb0147e567c45f4e91a11416c082762e71b5c6129c08\n\nQuotient = -617dbaeb8c6f9d584e8eae923c872048f9f9bf039ec6b50cf8f09c061bf79acc3311b37c2502e560848c05ab316fe8\nRemainder = -1ab4613767c4f1f7d127e848f2bb7c72a3a9e1dd6173b63198b80d3bbebce6a31494f19b53ad9e3a77248e6f9b26fc59060e2759a20dcdbe785297bbd912da9a1819527fac550d64bfd20ed1f96450c30f3\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 267d9397138fd0374a7a58593d41627ba1203a646ec2c04997acf607e9d217b8f40183d2f9304447d6f7e727a476e636ded4697a5ff30a9ae3d249baf97969658209c1b32ddc0edf920b0b278e9b5464313\n\nQuotient = 10ad85703fd51870306c5e36b51512341d6d39e0bac47a03732787b2f62e49c76666f7f49b2596de6cb5c5b2f31b\nRemainder = -846b4479713bb19ebb8c1f1b75d2be0f39fc1095a3d2ca149b5565146bc19382b86e5ab0d098ab1fca1ce701d582400190fee34b602845c3c0c498925710f0b9e3af2412ed5ead1fe03d77e9b2b407ac83823\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e0ffa4e120f2f46fd1430b6022fd03f71a22f9b120f8d40e901279be235b32d94760fb8c2403d23cdeb728ae73e2b16af7322d6ebd5f5673187668c99805e700f1e997423886bbcb851448dc1ed4cd66d6598\n\nQuotient = 41567bbf616ab41da51108d7edcb5a8a4877c5a8663b3aed7559421b1fcf4b535a54989efedfcc935b3917fcd\nRemainder = fc026e554a0821e0d36b796fe6a676fcd7383a55fd6158d78ace4edfc3d8aa87c65f0eb41baa2aafadc51218b0562ff4b5c9b17bbe84afc491d9e309217a5138ad48dd51e1b1a9aa51d69963b608ec47d63fcd3\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 396e9b45ce43d3f89386cfad8ddef4b483ecb5173234530c67447ab74629d246c18b9da09522c77f598957e3fd2a1c0c9417399912fd547fb1023ba6b90d63d223bcbf3e7ba155e51bba7e8635aa5c39d2b9dbb8\n\nQuotient = -18f1f395347ce8df530d9330c61c0e30ac9531b50a0af2ae7809db1258285c15ba7a436121287990fcdbda2\nRemainder = 51417b9e9995de34316a66a2f70c146df8e36952fe64124819607bd8691a465f4fde98e590dcd56f0faeb95d1b67751081c2393626713c27ec2a2123aec2a4ec3761e5ace4aaeb612d46e52e16d72a186d2ec8a7ff\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -966dfc779cbf9c388a84e947d1128e2392399ff45d9491259c7cb19589154f82f41e852e0c6bb5a728f6e87ff4ff95abcb9b2b57af1b6b7fc125497775ecc1338e4bbcb5315f7afde4e283347184b908545211afb6\n\nQuotient = -3fd962e88dc1d501fe9335fff8b6b2d50eea967c3035a3dcbcdc9599b81f9a445ed5a6ae7413b8865fd4\nRemainder = -97f06f6155f8d0ee6850728192e0b4fcf55fbd9ba982c5f1d598ddcbc4e1c4be0e209fefa6ab3b7eb2b4c645e4dc40217202285ab0a7270d085dd9d4fd24e5293faf6797b4c3c79bbf3ec63fd82942549f9e8f862297\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3ac566d6b2d18572360fbdc626ec488aa316a74f33d71a17a2d0e1d2bf26395623eb91dc4abebf2f944e9bc3d669fae2e4332088e9ff9d9f43927a7888b1390ef60f05efd6e63ec606ecb3e164ed6dbdc9d088586aa71\n\nQuotient = fb5ce21bcf28490afb64e6746a1a81792c90eae17407c0b4c5ebf2464eeea43e516be2c615f84901d\nRemainder = -3d255bf94c3d610c32266fd472d070c0f5e7dddb88d32723b2e1a20709aed2faf28701e0d0227c2b33ecfa9e708e5ac354a97be732b786210d86f1f05d191513386c580b1ad1f4ac6890f87fd0d4270f23cc5c2064502c6\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -eedb64a6e204ee3d6df508830704f1d5b2d2e627698d38a114c07458ea0befd593a80dfd2e08fcb1893adf57061ec4fbcd3130692de7c46f5ca51361e9b79bb7a91963618b8e5b7591392a5f0e3be954e8b9978c97f12e9\n\nQuotient = 6933a3123d0b32693351a834751345300c49324b861a663e8700bdb3b70ad996747b284a8ea5c02\nRemainder = 13849ef93cbc77460c3c496e8f31f7e01a98c21cdfcd6877547161f9601680665b394933d3a0824f0d32854508c89f0e4a0873280c779c7ca636cd89cf6ee5d42a917b4f382be3b9654039f623c11b43164827f870fa0f0781\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 23ab6042240a7709d43de7ee17332a9710bd0d913c42b3591341527bf48d5bc30abb962482292d45a15cb03c9457cc8d78d1e00aaa63358427b000e59e4260bfe1e2cc603e175d7fcf02bd9f61fae3740cb8e10a510ea3d1d5\n\nQuotient = -10e67cbb33dc6e24765893a047252766c2bfad8385150689dd4fec9ef495dff63ede1fdf78bb6\nRemainder = 9dabe2cbc734b910fa1bd25616daee5657d25b6e4dbc2cd93cf8549715c87974a8336fc5070d86c11f6b670d4b3bd5ee8ae3af2bb321fbb4f8fade3f5c6c2d6c366b4d800dd13ce897f13b0d3fb79f1d9ca525b4e7286c56ff29\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -de093dba98747499f2876c8b6b7a6b9587284835ae35f0716dd594c826cdf5b9179f2c6b08d800a77a6936602ff2b64ee0b7c94493bd5009633f5bbe423454b7f018ae96c21230510ab4bf5db394ff153b0e9eda3ef90eb4c253\n\nQuotient = -521f5e35300b9ec2742ff472cf61235dfe2e449772afa638b1adb812cccf269afd164b7602\nRemainder = -2ad10e8758e1d358d4744ad344ce319617027107c0b8db195d1b58c6e6035450c9b377f026fdf9e5737750af5615cff2ac3ccee623c060d779373136d48a735b353d64bcc5f2e6ea1e46083fd799b5f57dd5ad0ff3e6df9764af977\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2db1990ba1e353a1a62de1b914ccb691380b6ea937c13621a29f0a40ecef460cea52cfbc77d98706fb3c9939ceaaf962fb8003b0cfb40535e0dee22e8e7d04b5648fce2e58803242c199421cc4b26cae776d3603f2ce410ddd1e0da\n\nQuotient = 1d45aa6fe6837a1b7ac95efd55d1690b66487202949a286fc85da7ac0b50b860215e44fb\nRemainder = -7984639b596f1d4e6efea9d8b4719215588620ac959034b303584679a44fa84a4be0c89fd2e29f54e62959f9b7a858c06b0cc051176af82d4b85e7334555ba11c39e6cfa1829995c383ba81dbc220e527e90a1d440c1d069703cc1370\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9", + "b8b71372b\nB = -80316fdc405bb002990d3ef7d0e98defcd1f0e370d1e51db2d21ecbd96230baf69d00b168afcb7b8da9edc3ef7f6621ae5c5a0d7797e5c92283342e42468dba1036fcb2ffef1f493ff97826477364f6b5a41dc56d6389a01b83eee041\n\nQuotient = 3c0c3f7a777e611d1bd0d17d669a1ef7920b72ea8de06d4b415a73b836e37d6cf0780\nRemainder = d8c77134a75584ecd5ab29e97a909ec139464901f9cfcb1d3d9e29a63d204615b6845d466c8710873980f107c40ab54eca9f8933ef6d726f9bd0f3e9e97eade5eb1a9bcaa7b01b6ad51ff3ecf67d6e4d345f128e990494a2db434fcd3ab\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3e7dd961be36c0c286eb9e78bf3b33e6f9bdf2c2137a0c660f1d21dea31ac9a044e526bf47ec8190e137a60f1f55e947046b9cd04a2485679e48cac80a1bb064a915208889289d63a6e338cf7069ad799861c31ec6eafe02a4ef2c2641c9\n\nQuotient = -178d749de2dae3a2ea4898c59aaba98ad9f340762040f5aea13cad45a793f1256ef\nRemainder = 6c5d9b19aed9f099255b6e3d251aa50d1e534e6c86d82eebe097dc8dd0748201e48ac62eec070a999c21f5c7684e5a700212e9079b5fb731321dd1e16ca82ce80c1f5c17fd1720f1353bb90997f47f5fce335a43a6f59facff0b3724423393\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9f52ead13916f9807d0cf0c6699578af52c54816828f22de62328fbd7b4fd6c3740ffc82af4e24892092c7ecac44b5e775944445e6615fce25610984030a345731f944128f5734e6e315a0ea97aafd7563105695d026880d065761687b75e8\n\nQuotient = -4fe43bfa9417839ee408b254603c3dd176653b6915a89de5b781b400162fbed6\nRemainder = -1c15816e03751a203ae23c48965c8541849b09996bc81d28e28d7871fa87d1c3b2d383c056d3084d7d01d853bebe270fe2c0839e71851e169d417c47caacab2aff8a8e05f65dfb20eb17ed8f67475702fa83087bd868246cbb885d52639797b85\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2ef8419306ebfd215d9079c7a2b959a53ca2f4553845e3cd32caab2635c0e77fee8c5c016c121e3cbedfac57f810c132486ba78df9e719a976e0112516893f14cf9b89f95a89aaabf31cce509ac8e7e62ec3833f0be4336afe6d7d73518141d39\n\nQuotient = 127e8c06e12943017f9dd57ca24dca0ead230092811d307386c81b6efe009c\nRemainder = -24f3431858d5aee412443feab243b465b849f5dc97e4de4db88c7adf774d9bdda65fa0a28cf6b18eac6078b00cbeed2ac406f8426aef868d4b59ab045825d4b0a18af6c9105e32abc72fadef55b221278d329ff6fb9019630411bec143c4156df7f\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cae6399216401dec0f8ff5eaca884ab061469082ee3a18e49e0b4d5f9cfc98a598c373249a8ad2374e0b3de71370e93a98650684fbb931aa5d8b4482cb0be142492bb71743c251346df66896806f926a4a5dd4c16ca3294f01bb998835e6583d29d\n\nQuotient = 3f180694e59df85f48ac02b6d4faa26278af9641db18d79f198da5d802f\nRemainder = 36cf82dcf8c7ec783b4de68e0627a4a4b2a508637c176de09feef62dcf382bfa5d8b88539b5ca2cab6cbbdbbd0e54c092f00ee13f4a352cb570034cb0a012cc0fbdb6ed32967f3b81d146f352139bd3d9a5c27789468b7d79b84d6a8f6085f859532f7\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3b7983bfaf565c5ca444367654a07b8bc2bf7fdc04ef12128c392bef2f6b67d9475b4d2f0ce1c380913aa98616fbe1d74dc5c9d64df15f5c9b87a8bfbcadf335a6e8f863c7a01ac175a7d79645ababa5f961fad7d1b9926f7284e254fed33765339e0c\n\nQuotient = -11f635baf7b7d613e84dc38978a21ade2f4cd741d0c4f6ae592d93af9\nRemainder = 4317c686dfd56216bc4865f8dcb6a3446e13d8b33861e74d6c4a3223c387ffb8caeea0141049898609ed1abfc2adbd21756cf64a72272aab6c0b8f2177419abcbf9086635dfbea80a7b884181f2f2ec9a402cb0505e8208909fe062d5e6dc7094d66af62\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d0ea50558197566f22704e66a70328cacd6f4b7ca9b00c16b7c4b4e7dcbd47c9b2526b3858ebb4de7a571ac570872f3b44ba1fec655c0778a8a87ca24851f6072c5c0b7591b5e67a8cdaca78fa46f201e02379fcb9a8470e4a4971acde36cf501d369751\n\nQuotient = -64a078497f85588d3402355bf3e83d25ca1f0ed2c24a395ef6de6b\nRemainder = -87fc31ac66a24ebd629a26209ccac1b2c85e52dc83c5240269ae5a27333f33d31152c9470efd41472af034e8536bbe94b0a49e892b1d23db3c13fd84b7395d7e3f19d7d4cb4a4c07dd1860826696cf7202483446452aed2b4980388e7eda0ccac792d77a33\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 254a85bf512d9159b00a70678239902ee7e15ac2790ce5747c4a4743c6a0851e6a179b64c75acf312dd37a7b82a729246f79196b8a399ff476c48a05f89c29fb106bb06ef0300c4b330a7b2bcd4ea1e82584c7a96b99ec2131c885c5851343cfa6ae4d384e8\n\nQuotient = 116a06b1d38067cef9f55875fee1254c8ce39b42c19fb232a287\nRemainder = -c15a797fed3810e4f536e9509564b2142ffbfc0c961ee5aa923d43a824765c05d2a99fef79bfcb6310c77a91d9bc6d0762bd687493865de270c99989e891fbf6da7ea5c7c7a1032449457eb73222a011bb755ff44e4bdce8e86f8aa9f687840c0832f7fd8ce48\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d77c14100d19fbaff6334ca6aa504001a1d56f274632dc89d48e1d517935503c26b60c047cab9e186a55b72439761c884f63fdd2a38ca1acc653f6ccbb4b7262e6215e6d00c8829b448b7ac8716fe0bfdbf8088c8c61eee8f8db43b7b5551f6278081ac2eb1c5\n\nQuotient = 6fc9533f6d0e6c55494cb1b319ec47bde8e621aa92d91155e\nRemainder = a1a70f674cb141a896c4adace0dc58cdcbe2503fd0ad36ce348dc5b8afc96d0f2f8c65bbbadabf2920012798b7ccaedbe8d896dd2674082ad3cc75b54c5c190ad56ff34e8cb5dd29c031656497d48571295d6da396d5f4cdb652732d874a79a674d06a1d7b979f5\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 21917f48bb8e65646c618068fd9069c06e22ce8c679a845f9c4ec843849010abeee12e2d3c61fb963297abca30813c446f2ae82e909ca6ac7839fb58974fa65f3b5d91fb8b3f99d948519ed56653d50026d694060208cf48e3c757f64885b4ed4328c6f071e9f5d5\n\nQuotient = -1abc689fd19523d2e295f260d248041bd00ad3009cc7581\nRemainder = 1ab5af1478fe7373d012befb319b53ff9e36899c1749ea763fb74f7d24624e70ee78faf3115c2a423629528f45295e4adec7b122b993b5c29260558be4831df06468bb1c63e8afcfb1b9b533ec6acf754563d2ae25e2adb4cfe5ee3024611e03a156484a130ee01f3c\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -8c5a7b6bc8ed6ac015ec24efff607b0446c1b736dc8b409e2f433e69d0ca015d70c64b4c924175d0e0102ebc3e1dd96dd4d5bb01cccad229e699f9d8f9ad0e04339d70cd113e93d50c10c03083a81264396f5db2d979d272798ed30efa15d52289d0c72f42582ea56f\n\nQuotient = -4aa210fbc0457fa7366a8aa9a3acb3f9fce812303ec9\nRemainder = -737bc4fdd3d5496fc7f936ccf14bfc3d93f5b7caf4718c444db7a3228b41015c67aed304fec7704ea8238ba6cccb1e94cac3bcf4764a44bafb49e5fcb0339ae44c0114cc304b9c4370363657cd2bec09bf962ccb21f6091b081e71d2bff8556600576e18d4f78fc68b12\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e45", + "8774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 324774e49bb429553c10156e8db122670d6dcaf6ef5291f515c517d7ffaee36ec5ec5ccb4d12dff71ae7a05bdfbb03ebaf4dc6c4e8bfdc165b77cae20153c27d53bf27d92ff25643b4888cb586e773955a1c02ecbf0fa6958a8ec0b832332eab2e449be6e72c48d2f1ad1\n\nQuotient = 1c8631a18d189f1fb689f896005f2dd2098e0dae9e\nRemainder = -1a1ac9612fc3354056a5378de5b315f12591ee71f0fa9d8a6b2ea2b1c4eca9947e5c4f5ed3d4b78e69ef7a1f5a9894b9c7d85f6e2244ae76881eb06584eaa98c78b60b46084b517f4882758691f91d9e2acfd580d5e901dae14ff4a4fd6b0d7c73450e4928fc6f02fb5463\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -838df2a27bbb033fa0e581073b879d6e8747fff38539801a1870f2e52d91bc84cf10f2560e93784650fba080304244dbfe9da679f207b6920be46b0214a1e490537e56d99beef3f58b30f311a12283501ad79a5407ff209d19a6efd0421aa144e0cd427380d89bfae5d1f5c\n\nQuotient = 4213d04b9f0b30026bd355404bee887b22b2cf9\nRemainder = c2bc097d1c20f050e88912f066b658446cacc7a4d510343a8d88ed007a8c0cfd5d44fe5f067a0e81536d121b39f2d0feb8dd053bb5632e3f9c04be5f6bf4091d646860cd38c96271cdba466ef8b7e2377a51d5669117e664269fe3c08a51b10e1e019ac063d670a3c7db12563\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 38ca0c2f03a5c56676a2f95cd7a69d4aa2085343af6b1d2a71e0d1c54157ec0e8f9125df2a499cdd484c04feb23b1e0042ca908db74744584036c79f21c25c40401d551a65afed0ef35f1ea000fa1a99cb29e6307f6ca0304145f7e483d008cf9efb028ebb654115a8c6b87a08\n\nQuotient = -134e043b3b88b31f89ff4bc709cfa1bd2c1a8\nRemainder = 99c1c846cbce5e9a26c5afcc0186bb1e43b2501ab3205d13fdf01dccb9b1a935bc1cf8adf74d58f1c316381577366b6d126da49991a0d5e02acaa678085f335ff8b8e975e5bf2e52a05488ebfc21a3e0d0bc5bbe67442f77bfc3c1f0c03b7f7ce42bd0fedd8a498f018d8cbea47b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c261a6c562fcdd56e67fbd2b91027f17c95da43175eaca6e4069c16d240ebbd240582dcde953eea739a4668fbfcdc6af8ff3ab58674c95de90fdb43f64a61108b030d644a44b0319b912bb563f61e520dca9c88f411b32e99c872cf00a01f5badad584636352913b7429b99ecfbe\n\nQuotient = -448c4922b7a7d5e1efec2c3f41d0264b76\nRemainder = -2599e928027d10d3a11056eb719768e5edb1a625fc0b8a1dd4439ebd30a82bfdf89e617ac7c71622058cc64ba32dc242d96fe3ecb856f1b146f831334af562cf88139a99410dcb869b9ad6ac4826563b400b59f55d8fff262dc920fe525b12b2fa167ec237028a098c9117cb77bc3f3\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 36be11eb72832f8ae7b6bdf689f794f62cc1c885e64706d14a77a11df9761c2e9cd81d8f6a0ad0cb1696c69afd80c8bb992cda5100cf1162d600515568b9dc9c81a518da9d240888d4984df65c129ac0b4c557b4e63ee5be79a27473ff5bca58e559cb04c4ac93b61545e7351bb6514\n\nQuotient = 152474a1a76700598c18d9301866ec00\nRemainder = -274a2f9e2bc5f9d75f9897b28f840b71bb10a3e4e7a35ee1dc1150be61130b4e0e987e8742c5edb75a1ce3158eb8bdb7d657b8ba39436d7c88fbff160c7488ddff2f13b3b95ffe149a3d0d2d406b1737a7671f69c0e5d7074a151cb2776b2d13ca24bec261662f2967fd22339ed6c3f2b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b17c79a31d5085b49793b6a6d628109a6047e3b1afc947e5212d0a9ae32b1955cfd6fed07fc60634ad15f32a9e402d7d5f750fb6d1ad958211f9e8ecda8990689e5212cf72b24e9b51bd07a6e0477dd4c02381d0ab6c0ad3cac1f620f723ab004880800736804751349f6bb19d3db48da\n\nQuotient = 5665f53d5a7405c83a5ff382ec376\nRemainder = 252d055186ec896cb3142c9e4e49c441e2ddad365b86ad21ae4ef1c522d3306c2834d6993a5e1f8c64a1ed582bad8ab746f7e773fc004b1c47814f73560db72f7237ef6e2f671d3b19a8777be2e4c662a76db87ea64f32c48ea371b1ffb15df26726854a417e18afcf49054c6d2e0e337e71\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b6eb2caa3ca650be02fa199e9ea6c48646a76434e268713753a547e49571f9817ad396f2cb7b16d307801fc8892f0af3e7f93ce08f7955a8acfbc0b56add4b4c7ef7351f60e402b9a8ef7fe02ccdcb4b00b7ffe78c7009268dbcf1d606c3a1b5307d9a8ee6121c6a635a742b8bf36b56cc7\n\nQuotient = -eeda035247bb13860f228d8f2c\nRemainder = 3976edf710ab42bf069e5829de7e16962d1b765f6ae6ad0ffabe723e21ab01cb9f3f5f4edb1d8c13cafc0556c0aa93d72dbcff754ae9260abd294647b71785bb049bbb865a26bba22defc458a14af019a796e942e77d03484028aac2b3798fa730ae0193d89728bf80a8728715a0807b3c497b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -fb5e55f261aa96f54983869d58b3e9f0757d363b9c43aca5580b7c0380096f396ec79d1b30037702c19be5889fc6376793cad51975100f33ebf43e0897dfabcb9adf3adf8d845aa7589ba1f6d155b25f73dae3b2f835595ad6050401fd4e6392012d06194af415b810b0c10a53bc56350bfcc4\n\nQuotient = -5b37eb0c3e3f8f8d9ac6f4e4\nRemainder = -28fde388257b9a11441c592580cd38caf2d69e2ba57d43151c77d26535226e05e08a9e6d8ed470d4354e9f46b7626e5f2b22b652a2d78f817bb51598c727a765941fba63510b58fb3dd5f30717f237da43b42d20bc260b06d488c9c912bfcea1e7808544c58960a3e1355c50c889cefe75d4d9937\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 29232a3fb059242cae6e0b419ff13c479048cfe46a9063188706c6a3842674b16a1aeaf771c5b0ef401d2dc8a57f6fb4fe1b3c7bb545c18ae763e39421e6a07c4469d234f9fc737ac21ca67a5553c7ed693eede4325dbd132dbd9889d815c02f426801eff1f46e7a52f72845234acc6c153f34065\n\nQuotient = 1c7ac058af2e7bfbda9484\nRemainder = -54d7aa6dace87e61e24d87053b9d094bd160916b720d7cf4f740a4fc5a7f03909773d0456c530ea0204427146fd44d3ecec51d8627b5768de1494bf42081a8a4fa97163b0b93b59e70e533f3257723e441cafa4aab471ec4086601021c4462e1f74bebf298ef45fec98fa8e6ea97415f84c93c12633\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -83c2cdca7577b32c20e9e20fb498a2bceb7174ea9aca09d4dd2fc7a1d3b922797b4e9640c7eb9dbdb4d93c7fb9daadd680c1c7645d8102d77e9c877a9f65b13239f9a650dceefc1fd41ea9bd2b38a622bbec99cfddbc6e88f377cd51cc29fd17a27f3d0d970403a2aeeac6ff9fd69c3bbc5c2b0fe7e\n\nQuotient = 472df5f4393f33cc382\nRemainder = 16579a289cc776a47611353e158c43dadf0a78833396f8419fcbbe47d90c7e840e2c90e73e563e6c505bfcf691120ab0f1e9ef9c31db608cade70eb8e487b1113a46e2b5c7f4a172ad99b502eacdc0f91c295fe608389e61d030607a94d09d349fe1a0cc46d1e07c8db533cedebcb4a3b89afd8b924993\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 34b7f6780620246f5a0a92a768072185f02e57a52db1d865c21c952f4386ddb7e2dc1df076316cb4f2f394397cbcde1af0197fcf33e6428e6f5d42a9ccf623f75fae5940873097d4591d9b1a4cbd00074d134272700ab06d901742da695c3ca9d4f917a808113336f883e769fa8051cdcb0cad7cabd1cc\n\nQuotient = -12b4e74d76bd306d9\nRemainder = 8768fbe8ddbf60b548938d8b4a74c4a326ef335257e5f513e65a7d2cfbe9d456425ceb719407bde3cbc74c9c978970597b5663a0ec6196", + "2e77eb351adaee2d2d37f1fb55b5d2ceccf282ea3a0d398be1dd1b166d55dce04a39ef434fa392893618003adcfa61401276ce4e599051ad93152e3477ff524f0c\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c898a753745f0fc178227a7004d917557cf3dcae2e85e95aee51e137b29c895755853ce2d61f214b80070174cad8ebc2795a7d070790acd335b383f9dc88c01227eeab85f1f29d76c1136ffcc7b9fdc073a3a03d8812c7c561b32d8e69754fff64acfd64994b7e9574d2a7cae6bfd5a6fd61dee7ee993bb7\n\nQuotient = -548c97fd02eca7\nRemainder = -939e90e281f97a433eb1c6510668d0fc448f03d737d92693b6362c692167add7e4442105d60ff3db29c03ed06c3121aa4a53c4625906519a4092e4821c918d2264ed0cf088b7da43a222877f3ad9a9fe8ec06fc66b9cfbb44e0fdca1dbe4e461dda9b85231b5b9733e0c78852da83bae557755de3680ab61d4\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2c61dce04200e725ab0ecc5016f66044218391bdf650bc0bd31f3749ac06c24707e79526ee459ccfd4bc22834f8d23f391f2e99135f92b5abd0b04079ab75a263c0e98e46edfb440cd865269ed7872e8c1ada312df1bfd6a5fcd2ebf548d7b7d1d75bc36f62e5e9d15262bb8652a8041e5c8f4d673eecb777d1\n\nQuotient = 14622572f311\nRemainder = -6d197a84d2ed486327790059adb5c073218c56345f48c15caf6892734fff0aa7af4782738bebf24d984bc8adb3056f67e57f9960001a67fa462afd8c57ac9d60ae6517d58ffb4773b637ebe6bf2473a5490511fcdc576a4c40ed03b3afcb2fd27c57b66a26f6d3f9b2bb101502b1117ba3ce7214c9db6302fe20b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b818674faf69bc92085b7230d9335d7bead0413f2905539a54e8d1233843ef13f07cb5538e0787097cb24f152cf54a92e62ef143e31cfbbaf3c09650b14229a4f61a783eead26430949c88a87f1618788abab9728aa52dd8419f5d568e6a109f278b2afdea91cdedca43e562d4bb8fb7f1b7aef13992fa7edc320\n\nQuotient = 5cdbb03ee\nRemainder = 1cfa68d5da7a600a7ac598b9ca1a0759f972fd9a46ba62e5e96d8f6f00fbccd0ab26ca03d14470b43793411ea9803c9409908625fd74ef8f9b2d7c2064b2e3439adcb684e6f01432a1feb0f492fcdd2b8b5a6cdbd0bf460272218bcf763974be8784e5306c219ee535baf5541b8580952e3690b585fd99f77c46d69f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2869338cd16322409d3efbd328b27e2ba53cbf71816ff5c093849b1d866b8cdecbd6bd8ffea0b7787251acb760f85c277ded21e56acef05d29bc728cf44f55be87cb4c8913408a01a1ad53461058a1cf94538f05ec14a6d3eba804264df957de7eb1a61b794a1141218966463dd42402c260c229241ec46afdb5a06a\n\nQuotient = -f16da1\nRemainder = d8b66b622b5a54963c2c84aa186bfde5b67a3562e07a23a5f6843bdb615a3c5d4f007ad8b275ad7e4c5b1436252efe35699cff2e0546e6dd8c7230d6ad560c51cd54db6d312be32ae4c708e9047c3a25c211e2566c58d6b9291de31612006d4e847c6916702be99b3f7ce40e1ac842908acb7f03dc120aa8998c60737\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f8af8fb7002a9d2218dcd0f0c139b8e3dbbd48e25a5c910f6d0b6684bca224f62768b64955580306bac6bfd45b99ad77483563fc7dbe015edc06bee3ff93b0afa8f5866c23c7a7570b366550490c97ad84062c2495cff30717aaa965a8e15e270b504dbd4fa943be4f97a7fd1f3b589bc9fcf4f907a7690d99c978a374\n\nQuotient = -71bc\nRemainder = -13316e9b053a06520526f579718c326402d2a9686d51a340375cb53d7cebba99c8d1ae93388db0a41cf55d5753dd1174014ff3305fcdbd5b02de9e90c45ec0d2900ebf6ef847c2a045eab7f80f07f01c81b9fff093a779a280ae42239df79de8d2ec4bff6723788c86786fe276ae6a4dc1472442b552258e1e5b597305187\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 20fe256859a2e4c4f77db6adef78b2aa4758b29ad0787ce7e277bc68391d5949bb4dd07a9b1a79fe890c8a760871d81adfd3858e27d1bd6de33fd31b8aa6131fef9130a50f995c3be1d615d1bfb9878804b7f6494237d8ad78ac219488f17335ae54b494532f03a3fc8e9576cab6facd90c662658878fec86db66bacda3a7\n\nQuotient = 10\nRemainder = -23e09736f469c83f280052ff01071b1bdb52b7e2b061e8a1a8c6a4e091fcd7ca0b33ade885d928a11a3375599aedfe554d1c2289795daba08f07327a19a8adfc219592bcdf9fc5aee5961a48b3b1b5fc380eff5ed2ba7d7e564462397fb6c6187254ee41c74602b141d7adba99205d2e0b35da57efa96397b3a5d112751cf7b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e849bc0bfd9560cb90e42c8e4e88df175133c14466e530716d89ad0326b660b0e617b4efe8df6b000f517d3cc24d9dd4cafa2773dafd4c6bace0aba54e43c17e8e3ff9497a97ed83e6408aa0aee0e6485dd1d89d52520d1acf4d587422b0c5cd2d5e7e81fdcf842d6331779e800f96628206e8be020ad4021789008a641f67b\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22004040a65f9b6f120bb7243c638cf3a4cf6fc58c230da932c79568f68e31af7a7b8569aae77af671f8335ae68d6dc1698baa9d6ba9cd633a662101b45bde51d55098b50fabde8546f317ecc2ae7a39521bc075942e3751a349f51ca3c371f3b8a6cbbea3e11a334d677c07612bcdca767194c07fca78ea8a06cc3b0dc6dcb8ba\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cad46f410062dc33ad4d712c3b743ae2b7613576b2bd7c346a8479ed679a08e3644c7ee4f23b95f1cc9111905714b170abc37ee1003956f64f0a7e876b38d524fbb2436ed56069479d8d2e4029770f7801a7278fff99b3dc76280f35c7d43ee594073f725554a92eaf4f785c18a7cf6669dce5adb0995233241f3294cfb5bd8f4741\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2fef69f9745646aa13e0c38d77951161a1f881a7ceef032698da3fce00764959f11140bec7d7f53d6777c3622453d4525fb068da48047609d18d463a8fbacde1d21035963b668ca11d5b9ae66db13de7a7a5b66a40608dfb56d9f9f0c8880426641083a05b5ff9e6ba0d6da3a04af1af01dc218e9b4f6ad7b1d3a4d1d26a5c906093b2c\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee", + "8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c50a24e5ddafb768f64677233c5cf09da1b4f06894bd68e194b23feb5c5d6844320a12a02d13ad012f13b1438eedd6313bac9c1f9bb4548fcd314988d8fe0ce6458306735307afe08a96a0c2bcd9cf126f529e48b7ff4b8266caa28c40b5c3d2a473ab8805c860d27d7ee9c032423148d96fad019490ea019d40679de7a2a3323e80979f9\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3a8682d0e5a4efa985dfa8bbddc2c0d72a4400b8b070a8cf7450aa8f831d8a91c9ae3542641b7a4ad793e232a0d301b82664fe2c7f20bd9bf8275828a2a20027d6056b211638b9b0220fa4252d058bb485dd3c4622b1eac97d54b9634b558ff1bd5bd11085d4f3d288f7965af52beaa922b23ac0207d5763c24c085076128e0ef7370eeaa19d\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f00fb238bc9383079c7ecad9b9f6efc622d58a76f2d5d40ec7cd7c3c083c459fbcf3d128df4d20ead5f585505515aab11c36584ca622d28e0cf037419a649d598346063a07e29c61b7a8e76d1949dbce3720d45576763aa0d391b39dd6b694c7cc60a1b4f4f107d87130402985695e1847e82cce39b8d0fb5c88bcf3b37d6dbb90baf5a8553c3a\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b809f6baacecf61198856d9edbb768ca2df2abe9b7b8ce1669fd9259732c8569c0cafde2e32d253094480ed281a8db230f84e780c6e8bbf3657c0b0baaf19ea973fd8daa2870c9d79f3695d78e063f9130fe07ce806a088ca267fd2820f10dac34b5b32aebec20e4362dce26eee0c29d2fedc1e020d452bc2499234d07a2a6e54314e3fd6dd85fe5\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -90ed75629073df816ec1d6dfedd1cdbed9239661e362db706288dc4d774d806bfacfd4b32c3013ec67d8c2af133b46989f12f809fe202d33d5ba53659bd2a9a85d3fa542de4a5c656aacbbf8899aa66ba816b809f2629f37b0444cd3a6dfc99103bcf2a5ee87790b8401be806b5d7fb7064ff0a6fc8ec769d0ccbddbc3d35f7dc4d388d8d28021c95b6\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3f60052c9dfe0bac797a674ca7f11377a24c28a1396ffa0f46acab7909543086aee1995cf51852ea4a21ff4bbf6e7309cba9848a7b2e3b33dbe660bdc58d513d16bc709f1f2253648b46daa7aa037332552db1da81b4ab9850ac4ec66621648fc856a71eee3cedc6617071600ecbc5ac8636233f288ec249b7ae0bac942a5fd539d03990c4fb28a46653aa\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c12fc156d9345cdfcff94bdd324429530ad8caf8afaaa1a82297eb3a8aecf2ac021384036749e489fae05e8776da0deca7e4325436bc8f383bed579c2d67a456c4e23871489780d760d63d0bc0d1d0ab41f06a091b44f602bcdc0bd4e817202e39ca6a934c0c9405adb5a14d24da895c58a81d1c7ce52734183e00d80a414ddd8869998822364e029b3f42cc\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 205dc6227dbd3adf8ee49dffd43f835882822b1c94f92cf38f5efc62f943075d80b33588973a0e0a8ff5e800ede21d394736ba98d4eedc53a9122f8c262cd09fe9e91cedfd0237003b0124d757797ee13cd03e7a3a257bd8df756940a4d22face9287edca00ca23e7d5e629966ef710b07e54241dbace041aa6d9f82687c3ecba818203adb376ec0b201894a500\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -82c30a9ef6a83d81b77825c71ddc563939b8508f1b7e44c725ae0f61006646ba9b86507ec9a4dfd3755ecd8bfb451c2d43a61599732b8aaeedff7a304ce0a9327e2333f75e9a010556ecbc3abaed02214f25e1c8373bfafc2c288ea36b8d5f848b76295a141d8f633609a6656c07f3d98177f5fa83833476dcd111aad179001f81d6013ca3a54cddcd8dc0ce7eb24\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33aeafda3cfc20710f0b4a3d9ace4817eed80ca57ce6c82dc2e7946058a40983c9204ac95a1399fa633bc96cb10af3ddeee3ad2337c64391a42dc7794fca629e3e1e4e03a2ae24a000e7113b91c1b6230cce9592e45b6ee7984680b45aa0aabd7f56cab1a64ec310cefe5211821a75deef2e0c8e43eb467dea79dc8c03d2d523734498d079d5493c904a2ebfd8a3a9bd\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a1", + "9c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b897bc87a40211ef8f93645b1f6c981fa00ab3b12e117a89375400ab5f4c64bfbba01d265c7bc6f5e3a8e26de5de9df3b8f70f4a39c0eba577db5e4b7a68f751b4a69ff4a38915983cbf70dd7e066779405d572f5bbe0719c978b6865ea1a72d90d3ec8a8c146f20d98595036b3de88a7500d7b476644913e4b63e85c4e2632048e9600d553e560759770a902cca680b17\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 20604e080549e1c503049ebf4a56cf9447d90fe699a9773915b0a65588890e15bd58f55ad7b52bd7b7992a8b24704f1dfd5fd07c70aae4ccba5646405ff8a9cbf542dc334cc0c27a790c05420b552539fbf0a155861bec0e4d9e3fbf045720ea3aed58307d5738b64252a963f3fd5ecd0587cb4d7e159b4980dcb112e26c9c34f10a192e090ade157eac1d7a6f970871eaa69\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f11fc9682601cab97c25533b2599f50edb1ac65d46f1969bd9c3cb3717461627621c8cd401a0a0b91f3645b8804e095aecab31c1bab0c26df556adafdd7e7f4f0510e0bceefa3619e26b8c9a1bc613db03857f53e9eb5d4b8f75a8cd1429feb81edc705e5a779d5f95373d2243368ce17ef22da79a6a2672496bdf629171b7973fc4659c8eae9ae867cf38d6d7617029bf59d2e\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3cb0ffbd9ad21d0e86e4e4dab4d237e2a17d97356bdd305fda772fdd99acefcfb8309d813643c852f66e1c6c7fa41ffd44f8335ef7333b2b3e846139fa9be2c4ea762afba4e11263c0b5fab18c5efff2a18d83ee89844f5f4db2c1325f0f55e066a9e01030c07a85e2c9bbd37b5e767ebcc9b95f474ecff24df9ae52a19edeb66546a3a28980f616eb5a351cd399e5f8436f17faf6\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b8aaffe779855c6ae51807f8cba780aa64bc22e8fa5e33f7f1dcb084fc476791565bc33eb37b4f791ef5cf46d64576f48b5fadc9f096f20c798355861ce5d24a7be1450bb871f9821099f98213d74a5e5cf83b895ae65e0e0fd096698463906a112e6e169a1cc0769df7a5ba6812300fdd33611761b6339385e1a70f8f8b2be7679ca216f5b183140e69586a27aaa9f2fac118118875\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b7ee3ee34347dd89ba4a81415aa1269d0390346597b07444f0febb71d490a01b6fee174634bd88e8aa180409549b2726d044b4690353de2fb2294c8f69c612485aa066f68fdb89466760a85901cbc7312bfe5a6f656e67dfd2d4ee099ff97694b01d6d5b8626ab1650eac5267be53f5f3ced5dda1aa86bf42ae132a28fddb94902a515da40e0fd0586dc8b17a34af8eb03d06f70ab89df\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -bf8213944ba785e01b8d37a12de77b2ce1492f34bf6f67406cb51da89675b4f70f4d4f314f30ca8d65cbc48ee2fa1f0a3e4ac0de3a87d2c4c589b6812e850623d78ef2e46fbb555f6d3c69b211892c11a4a2dc3d8a9a19e96a07952602ed5ffc0232c140c3e828acf990e5425d8dd9ce0c1107ad1c6f96c8fbc90ffa457abab0d843094dca3c8a45ddad81b7850190625613a4851485f38fd\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3083421e375f0722b9397e156de47f77635d62ba1d51794469371b473b71c02e3722841bca2ca06b5d1cf1492bbacfa0abfe394dfdaa7bb8787550ddbd953540e9c97631d9a1efe0c8f8e14f395c82d20245cec6d8021f8564b4d66e7779c3245734c56fb74481172f4e349d9a113cd0ee5263c69ebf746c5285cd4c0fa91d9531f769fea3610c2972ccfe9a22c00aa62ebf52b3a4c6135f3069\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d736bce537f47ae4797faad797af8cfeaf8a4fd42df1f7e61febf8ebf6e47dabc48252ff7948f3dbf8cc369b6952dc58f64cf09b4c53447d135c7a753c21b6052a9726a47a61e13628edf0f2bdb357f2e780ac1ae1f28f211296c8961c2955b773d7dc2904dfea96780b2877af133c9591a0dd54cb20884f014f363862478ee7ec45236bfdcf0321af0692e68f744af28fbcca827ebdc7b210da38\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2cf1708f1e675ba688c0d19eb61a05d2c8642528ea6b1512375faa732acc59ec04ea0aa55e0049144be09eae1292b6cba6db7a9823f1e912df6a5032bb9674f4f26c0c8244ea0dde7acfda566574956cdc33e4a27bcdea25fe255c19f218cc4316ae8428ea61d1bf865197a066b959c5fcbd7c95", + "96207997d05fc38e32322aa189ea06cf5139522571661745c0d72b740dc6d842f1dd8481e318b5792\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -a9180e44a284b5bbe72fff46e55869f749b626ac33c8cb17be1fc260d7c6f460f24a89e1367112e00d0da4d213a821d09f103f35bc4eade5605bef23c5d048b1cfb45dace8b9c637af626a85fc773cf51e6602a7a5999a030030cf114ed6a4ed7583465b9303a72e7f60824c12329517c6763b0f64abd8ba2b9b26cebe882a51f05ef8076e527d53a213db910a5f42be5fb78729a3dcd08d69a709920a2\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f26e156b3b1117f7cec542b20fcc06ca66cec03a19b6f5eeebf22b4c0fc265df5ff06fc9dcac569735135bdc142b526b295225711efb71577b10aacda2fa446f5208487c725407c2188b3185237740c813e4455a6f1dde4f62916237f23164a3471aac0fcfe24ad1ce1dd81a6144f5861ad0cf22dc337abe10fc4a88b36116dc4929602ab48eb971fdd7a5ff747d6b9e0b2bff75c59621550991966a0a19f\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9fe18ae697576dd36ebdb621d14cac1cfdfd1f5cbb7cfa8962c5a7dace96f9f54fb4f4cf2e650dbec5d1ba89ba53d251ecef7dcc1cab8c2ff3d77903f5fb5f29a4e8e3a2a3c05c105d5733b5132f2f8d88f99d17de86ca1191c32ad8ed469bb649ef188306f69f183bd0fcc32759e4f855170f88c0a3f6745aa98f6225536821bfa056a42b37535a622f42b009859c974cabf2e14f75c749d0fe5a01fb3ab0c0\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33ab185854b20a8126884eed85181b14e75d4ee452958cc1043b099bc16c24b9c2f3e0b792744f230013907844496e600389800e45fd55133fff0cf19c9c152b9d031039eb90da568f9c5212a3ba283f4d1353ff8ff9dd04d292c265bdcb77c3e411716f471930bccbb8ddb819ebb0e0036dc1a18457cd97f4f5909a725baabbd15e8ce33875895aa8dce77a4dbedeb0271a2a4a17f77f5920c3776caa4a75ac650\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e7ca0c037bf8bad5f8d9c5a2737e044d9f7284c616156d142612a53eb217f57f4aa00b6daa424e6c0d9163939e1ad0510a1cd64fbd576f3e54c59d7aa6228fb3caaba7cdcc951e00ed141ac3a68abb9780bf46bf544fe0e347f677288e962fb69782741df49b27cbbe8720c6f8f2e769147d89df6e17e3c592bede2e696d384b9f01b99b31c505d67eb6193a8844f8c4cdadc9fe45dd446a0dc572c9da6e58ed303f2\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22b76d6973e37aff4a09216e57662f186c0a0748c4375d6bed370ea61d1f6fac2d9bbe04487a629118b6b0b0c8cc4179fff7bedcf048cc529498bbd9cc81ef3a103d6cac49d58bc41c83f961b6df7f00c7171fb7d9359e03c76e4364cffae5f67321ce646e9b05f9c04aa16ea65389e940022eda6dc740ddc070bfc7e589b86fd1559dc320701c39de20d54d0483fdeef6c4fd012850630b982c2e243ac1ff918377ceb4\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e6e4d69a82b83e26ef8ac0f4c3a211153ea6655b7ca12840e7b866510d114693049c5b8b22c3a097eac832bbd1986e60564298e54dba3316807ad64bd6c18903a0f22660c9e8d5dac180f57cbb90b176b842d5b58d6dd9f47499a037833a92a18f397238a8bcdc4afd129382fd6d200d3d267ca1e6bcc2cc65950831cb8e30bcc01665c8149b874c9f11168153c187341afdc43e4d8652ce4fbed9f9eac75db40d64344ade\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 319a81f052db21ee213c536db2cb8a71e0dcd0a9b2ce780a9588c38b717c5e487a337f82b5223f638fb552e92b826192e6a1c27771d1e86584bc6c7cbc5d9a6ce6edf2ea2ccf6939485959ccbf3183b40e410768c4665adf90a0ae2792fb4b5d8aaa06c6294e31893620decc3bc72fb4eb68f1e56b48e39c59abe869d07509b7564268d0b7f178ef09ef5dcde6e7dbd2a20fd1d4fcd707943dd63adf590a117ead1ad10ff85cb\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -eced809145e696ceaa0ee8f831eca67049509b31a1b15e7fc86cdd97a73a2ca05bfea5f4b283d287e49906463ef36f2f8ea23c2aa12d5534c08e9769055e04822be0f8ac85f404f5c025a6833b4115f78da9470451c852ba0f24062397d20385f58c5aca10f3f09072b2592e5672ffb989a390abf86cbce74268aef1f4ffde730b3b962df1088bf8745105a7462379ce142f819c2538d9bba99e094ffbc4478625bc54df16c5e1a\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661", + "a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2c1ffbbb30e71d5fa77b5473392f95297b489c85f83013262abbe948842473154e00c86b2e354278844083f960fd746a3b7cb9baecb9c66932774b3a28f678d50dd8fe52fbeead43d8c8adad7c0fcdbe5e02664b0feb0ce214c5fa007c5fa2d08c5fe96787b95639311cc4b7eb2a7217c9c38c6d93444fa60c1f52ddae9bb2ec1a49a593e210e47377d3623cd2c4994ad9343863443911062e12233176f4a65ec715b3c9731c4a0cec\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c3bf056b905c0392a7b5fa57446ed350f325eb67d59f1784c744b04c7f4d8f5397db913407aa8a7f1dd0225c1a9673828db0d8bf3d4908ef53307131bf5b5c4c6068ad73b874aab98e8db33b0a758532172acd8b2c830d0679a8226537090166317b8eea91e8ee4a7282c0ab0ab6f2b7b63d728d22b534fdc88294c376a8d036ba9a644c2489bcc84f6aec83afbac08067a7b93f3897f8dadfb68c327b751841927a728faba47dc44ec4\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 23fcf9510caa531a304eee8d0b2d49050fca83abbf287b6b6dea06501c5afc6d87d2924df1d45b1bf6c4bf77b563a3013cfb4ad9094f8ee9892d33f6ee1c70131cd5721c5af804a9da7654510e8591aa185ee723f8caa78046d9e6fbb891e6024d2ec70110ae61c3969995e35941d2c7f3779d5bb71ce5b693bc9ce4b087068adbb554acc4ab23624e060f7cea169ab512a06ff3d2a36c2b6e3bd9a75f1a9ad30a6a16b0256c42eaff2c3f4\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c32d5e643b12db6616554116299c1da672efff1eee394378c5e9e5f702ea4ad64f0dac8904bd2751d2cef91adcb283599f6c661967dbab27059e94dd50025489cf74c6897a22e95013669aa3063fcdd4b73aa6a9a1ba5cad3956bb26346e22df6741cd0ba1c0ab87fbe74035618a394383823216df47b910cae495b8fe7ac5feb3b2cf0d0ef6c75db477160b75324db8eeac48a0fce72b9abbd7079ce6f529a89025a03a3777cc7d1deaf3e4a\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2a8f2c530342bb6ce683a760540e956a1155c0fe065476e400caec59861ca97ca71e51a11b3213b2baea1a41a29449998778e0f533fcc181698d293f05e28bff2750ef4095170de98a19a36ddcf59a65f3789a3808ead51680245070262c9544e446f23652eba47065a2bc4701c55378bd49733619ed2c213f8ed12a4a317c465f37efe07ff2df8e88fc33d3eb42cde9408dda28215702bfa607030839285a8bbf89b5e8842fa7d7f50d83fd4ab5\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -bcd2b2362aa146cd120b729e81c98ae598804006d046a7ed0f9782baa10a85e37c7c22288dc61c24830a1b42b123d63779e88d7555028292fed5ada1793264b35e961b608bdd7398e421c5474c33a65059ef13787e0cedf4f8f032beac48c4b5e5a67417109142a43b198ab617d1de1a38d6fb4922c6ef70a5aad3faf6f8d5da3af9679c94cf61ee760ba792d2972376425e2ec9c4109e969e3d9c3dd90cdbaeaeb7382cb7bd024b75a1fd6d621c13\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3940430ace4b5b87bf4baa2673582db3d27307ca4cd8e55e976ea3e10da72b6deb7de932253bc9228c85cd4ae7766cd0264004c658a66d81e60bb9bf4dd66e2afe11057b7f7b53a1ec222510748be53a93970fb056e8082631b2b77413fccb6e61cdc6f224b7903d75345afed8a4f194b4bcedfee1f16dc256c2bb9f4a129fab6a9fe752895a93937a3d087ab7ca212991ff34f1bf1c55987a574674af43986312bbc3bad3280bbddf4ab0217440f851b\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f0dc20b88450f45381791e85d080e4f2cf38837391e16e608b8cb5e0ac0ca75e9f72cc04bf2f56f130d46aff31efbabc0ab14f0c0ad680d6899797297152be85ac012644c8d0927b5b6c70dc3e5a8d79ef92a0873ec22af3d9683bb5db1ffd5ebfb698c5ea64cbe2b6a8b9f14d4c18624be1b78b19eca14942ae9542012692cd0d5289ebf75fcf5486596f92659143e9f952af3622137e633376fb95e628055e0fb1ba3a37ccdf0af69a4c0d6b0793078e0\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f2135850715f623909e41a745eaf7b37593567fa8be2d1ccf76d10b93a096e244b91d8700cca37a2ec1bff7c3d21cc3211ea8b03a3594921dec32faa185e7f3d9d17e98cbf8d881fd2abb944181659242ede21df7e5e8784f541cad678df1ef6ca4a5fa91f7856c62fe593c4d24436810cf4fbd11125bcb571f6975d82afeb81bd0c7700e053fc175fb5fc7b329c438479a863b8d5fbe6b4436b67355c51d0306e8847a27a30c9e61f0e08232673cdf0ba4e0\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb8", + "81617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cf429f101a2e19a65af1e238f6745215cf476ff2609c846f10289f1ef21b89af2aec53def3f4ec07ea42041f8b5862dc37fd03b2df12adaa8c9f1933cc69b526d47797b40f49545fd093b8ceddee3c55721d1fa19b336218de0cac56d410cc6cff4e620578cf820f5cdaadc367dc4d6372aab1e0ae3831a6d153c14920b1dcf09e7629b7442a06385420d79742e409677e3b82ec58bcbfa668ca072e981e20728a983d84a432605389c855a6668e0ee0d2b67449\n\n\n# ModMul tests.\n#\n# These test vectors satisfy A * B = ModMul (mod M) and 0 <= ModMul < M.\n\nModMul = ae2ca2ce7addaee2e2b7752e286b2bb6a58b51cfbed5c924f00398e59ec36fe6341cd83da43a33a12410f45f6228079c4aeb3912be87e2e81fa1799151bfa0fea29873097475b2c3efa312145d0bf7e51b2a7c9bc961a4f4dcf0c883ff90b919b87c21099fba40257645be31f95a3a277\nA = 6b18497fed9befdf22a01d988d34213f6687d8a96e86c188dea4172e7c6095a0d18d3c86c0f5a1af9c6e3aaeb6baac2a510930b3ed06ec78ec2e12b\nB = 1a058d99397db0d209f01212dd4023ae01b15da04fe62d1f76f21622b2695558c67d706c535ca7f19b36f8ef2d508ffd6cf6fcf25e5\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462c7cdd79b7604246a0cd97b40ea5a9a77408f13cbb548b56ee713c690dac0507fd988bf28e77462832f4307b08564a51510d4a951c1ad7564316dbead2b53540090827a8ade8092a6133af0e5fac7310f787dc1472836178ed6992b9f71224da3e884bef8e8379a58e6d4be0fbaf59bc520f786631857213305e23fd5ca65\nA = 16c92f77c139706430f396f72ec7adb045745cd9f5899b0074d9955bd32de66f57c05c7929b575312a7f1c04f19e724d64744bff7b31ad0e6171437763\nB = -8734c4a2361fc530f60b28a5f1c7e93136c5ff6bfc7553965eaca54c61e6befb3c0f8cef4280e780cc5940d21a740debba31f863ded75\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462c7cdd79b76042469eb41a7a83115eb84103da4ba438c3e33227631dc185054ba4e607141d1e60990d8aad4e0bb0ceb645ce9ccdfe72d4738cbe1f6a73ed3e070194fa4feca6001c4a853940a227d15c1f1cc153d8c96e90e24805929fb11e0665e0c41c77d5a97fc5903a8b215360e26f6a19922d650f460f7056274ee92\nA = -6715098ab2ba3ea1e6341e89936e3ae913cdd450dc831c8534071f3c362841e47d88f2cd29c0d1239aa0949f3685f12f8519625bbf10b2c7a515e6d00942\nB = 536d4b3e4815ae5ed55bae6950f5a8a61d52439d2800ef1b5ba2285b85ed0f6ec4af9fa0e364a6b14f6f6b8bebce9200467804e787f9f3e9\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 309b3e30f74c58beca8b2c23f64fe1203830db8a7e306e1fa2e2022f0d6d422851da509d1b2936f088f0e35effe12a7463f47ca369bee2f2980bc48dd8e696b2d8c6f35cf55fb8baafc2e613b4c684de26129cf196741aab873f81e498b1e03018a539b5eadffeb5953029f31f8579df7ec0ff3f752491910\nA = -11fec955948e007b59fc50e729941ee9d43d552b9411510b73f6b4faafc0465f261f8381d96f647267f72175883172918b5c866cf1f1ffc43c55f3c96a60c01\nB = -2b3792f39499767e0a8b7a6a406e470a78f97ebb36765beab5fe52e95abf7582736db72a2ebfdb2405e3954c968b350a459ff84ef815dbc5910\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9143ec3e9f74a8eec476cab17ad8636eaa7c60e108e89ae0702dbdb2b255a217ba2530c6fd52658cd931b962054a9c20c8713976ef3b7989c40611cd25b0a9ad0635d61f6dc95dba6e0c4a7d53ff539b623b97ba3d66344fa324f905abb861c6b1e830c4b0fd5f6a4b01f09c8e1408941291b2285c4625267a108c\nA = 7713413d87f1e50840255927ff27bad79e5de5898725a876e4647913158cda9f5fa031dd7fc11d2e8130a0ba99e8706341c1a98d5fee3218763ceb1d131e9cdcc\nB = 1384e60753dd4bc20cdabf398525e7c4aa40065255c5058cae0b2ec90a3821bea8de672a712431aef5864eab719ba621cbbd8b46fe86fb31286091\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462b3b4a0432890d141c0f46a28190a2e30ebb2e4ba90ed132169cd72316b290dbf5c261984d98e63eea6525fa890bf52185ad7f164cf49f67ca91c2f35511f3bef6eb7f3da31a602a78e4752e326d79dea729f4ca6438f2aa65eff44bc60979b42e44f6a301cb5de8fb42abb47bce5633c6ae9479d39c9e8b507d96161e0fc\nA = 17d806d7c76aa8acb051fd9c0c782443f1b1b6387455f7cfb737c41658d0459bda5d13587055eafb87ad8d209bccac1fdc392aeca0774ea48799511c1fb9141cad2f\nB = -d7c9b6574354e131de4b8643d766641e98554a03238ebfce1112c3da5f049d6c410a7f05758571aa2625f7190b936a214797570539317b32fb94cfd8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 16c84ed15ec6352a8ce6d5c2bdc0d9f13b333072fc7041146e944a29391f83e346b8ac0bee6dde98a420ba4f8852801d7c5bea6f1177a6cbf799edf2146f8297013e0e796917cc967786788ff12d9c1d07d9ce4b897bd22a1b8a391d3b4ecaa5b5c85d0a03aea5145db6350c42a964a41ee5f83e7d35e14cf442e5d99ccd0ac8\nA = -6d84cdf18a2f53fe496248fafef183914d55c42267af3dd42a39515e80cf29211fd58454986f5fb6afb56170dd9865d3158249090270bb9af341c830522a4dcabfd494\nB = 6f6f3f74187b7d74dee92f79be864d0a2c56d4bca3283742e9cdf15112c8f4208e3ac8ecc98b44b4ad74b0671afa4aa9e48dc31d34224a1f66bb2b4658a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8fb782e4883ccf3aaa2d3e020b08993d580c69ec8fe66ecac152c5babc8aeffafe406736cea492450fe6adc25dfa2e12723a3f9baeb02fc0f785b3db760ed28048e1710a78a2ae0c96b67c109c5034375a512b6fc7906847253f66316baa0ef90facc9ab992235153684d49d6939ab9e91086529494d7386f604ed69aca2f53\nA = -1f745c8f0c8fe6ce3f893d77fb274c61b72b2d9f9c5a2eb2467bc00d1f496d0ad469d76bce318bd64ff1107ee5fcad4469f84d658586a5789c068b0cb9b866d8fdcbcac5f\nB = -3a2347b491813252e8ebef1bd181534b074a368d076b8c80bde2e54ec3b4ec99001f43080c7857427e069d99b1b65cff998a141ca6963aa5fad1ee632986ad\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7c0c1c05ae1d6420bd93596a01aa0153000ecce660a8a14d6fde7d4740719cc495fe6681a9a08163b2dfd51659b3ae7db0fbe09504370bfc695457d7b32665a4df53e879ac817bf715d5bd6ca0e242b1ebacb1ffd6698ec90c442910a92b35ec103b345f9a9e5c7b005f8028da4dde80f36f6f6e5675040d19e46aef06040eb3\nA = 4c09264420a9452c6f0b55baee42c076aae5a73697cc6bbb88b7c922f236ee4c18e477f88e2c40cee03f0bbe87d3ac8dffd75f635315f856a3881c6373e8b9a286c813325d3\nB = 10474ece7ddae5c53c4df5b594439124370932dd94aa5d5b4ddaa233b1a55634fb7d72e33bf1b02965fa9d1538f97e1cdb5ec0477cec8ebaf202aff8533211169\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 481543f1556df756ae2e422ffe35aae020c9bde9e9b1f760b43043a4654de363dc67f381c0df1c3c1b90edb4343c47ffb8345a1aaf5dae56f446fee08a0b9ee8c42fff57143e10846610a9925be96418c4c957b4e92af734b96fd6f21974877dba52a0db1fec4aa97640e357434f95ba74b6b8323cbe17118dc489552844602c\nA = 11bccd165d9fa2d8b01a48c0ec549a6e600396cd2023f0240056193ad27e971c604eda8aaed6ff6be8be1001f3dbdc8655f1ae84eceb963938ae7bf428eb5c968f584798c1bd8b\nB = -cfb6629ddfc98a242e3290959f4d0726c0b1770b52393bc7488a471a90f7f0951362c03e67f443c9ecf4987f530", + "3a789bf65e0fd59cc5eeb9f5d4f40d3e4a14080c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2a770ccfbcb2bad207d0e2dfaeed04b6e7509daef00a1df88e57509451739a8a0f15106ce8b53d280a4b4e09900420714cb6961ebb0e00e88567c5df50d2f2908b4bf8e0a9a5a8b3c6120503c14f16a99297459543c467dcb67915e0a10e19f72ed5b6891a6121b66abaa602818801d3306630bb04ea57e6b31b2c05e368d398\nA = -442c80289bfbf00db06eafbf06109b55f99786a323fc2c6db5686f99094cc24aef50475841243ec3ade2a1e0ff28b4032fd8afb8bb5e28f3b2863bdb9fc8f033adbaeb5f2ab16fe9\nB = 6d43e3c46f4a55d49e78f40d34033a7f5fcbe50873930e7c5452b6b3b176534e6e70033868c85b4d63052964093214dfd0bda6a84e893b1aae3cc72aa83d039e51c014\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = ba0e8c91a86af1001b13deb115c77609a1e7a3736a6b807255aee898e3100f469ef6222be532dedb1b8d3db4b3b55aa4b5da5629c83e9b2bde76bf2f2a4119a5378b5cde000980b3e58595d988ff776f0388fe025625ccf368e20914fa90dc771c826e4a836b2890e82ac2274471d586b4de5dab3278f0e70207562ac6e6493b\nA = -14be403d28c8451cac4dc83fbf895a9d2b74f730c39b0fcb33d7258f99211dde31a78f182ad1d27a559031d67d6f2f94a741f141bab80fc692afb452ee2d502099ebd5760ccec7f7ebf\nB = -2742dfd02134594edc6d3025aba5ca4a34dfeb43821ad84164510b43be4fb95748f8d0eed7bbcbeca14efe843fb676882784bb36c889be29bdad9270e0956286552119561\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 20c691d6544912fadfd9894cbfd42745991f39a29cbe3a1cdd302bd0487bf70c0179b9579b77f8481bee13ddbe42f32d734b6118af92884c946ea8576f6dec867c1c251c73777cad7c7c76e90da00ae07f96c8d6a751e5b18157dac4468c05d32eb86e74e0e8312bef85905af8193a3f5c799c5875badbc9eb7ead1258e56d7c\nA = 7ae9b4d5151b11bb7bd4d1569a6f4804f3b4d77948e0c6300e4f28d51c9a0afed2ae7503e53489edca5359e2b3d0c82a9cef316cd7e1c1275c31fc9c51a8c1e5fdf23935484e467d6460d\nB = 1f46f88d39fbedffa8501fa1268bdf3460aa98e12b629da59676e61852a4d3f8c59f72a2fd717fe2faa09639bc651ba516cd39297e0cac67444ec57c0db47c2a4e250033d02c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bf21b3cd55c0df8d4d568d00f757b10ef3de782ae71b289cb2b59d36df1341382bdc1825ba13199f2cf279a72968b3bbf5f7e3d13ea9adeb96d81132788231fd988eef04828119dcca21ec1fe844998909cc95a8d01720e883df27f07ef4dc3f09081015dbbdf019b96707c18b0b1db6e689e8f86466a2afea4a9cafc576e10c\nA = 1243b14aa3d16a55935f6f8ca49295e35e7f75b03de7192e1e8a479abc0a430e0d340acc05eb9a61a5dcbfe3ce3a4c5c940699f5043e924f282bd21e341edf8b7a6741c6ac72d7587a9e7a60\nB = -bcf08b2153e8ca911096189e35dbdb21b77ce89685484f574c89f1747612f39340bf1b204a23530abb36b2c5e195940b86ef1252d6729393c25d4c73dd434b6dbc3057b05d3f15\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 460539d96c07e72acba5b59c88fe904bf7f1e1648612908444b0b08172d05968b31b43456918b4287dbe01afc3cb4860d9c2fe549a580c989b6507094f6c241eadff910d2603f747f8e289e7a8176ca4a978bba89288a4cf875bf3e03939af966c54e77c28119a39d34a2b7055465f58ef2efe7c82ac547fb675653198e4b504\nA = -5a44cb669c055ba7c28d49f84bf8d12179aa30bbb9db2a48d7a6b09e44dc0e0f7471e3629cd2fb51e5a53346ae025fb49f9591ed1d71bc79daeb3f1254342d8a2b091ae07a758c1555efe59e78\nB = 646cc0f766346aaecbc5147a4488ce157a6d844045b80884eaee9d419087285fa71108b5ab4a05689aacc8d2e3dd0e6714c55eb8f77487a3fc5e56c3c2df0c4acf28a457051118560\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 79b536f4f30f9f7483f90e65e6456ef8072d9a7430405cf8c9377ceea2c676afc338837643436d55ac6af2326ebb362684bccc5092367209822581700d641cb8d331432b761e4c6e22639a27335f45a25ec019d180fc53dfb53d69216d7cfaeaa07db8288adc35b7bbccf2829631c1eebb821e4d3299015c3d462dc17aee5024\nA = -167529b1e8668938ec02a68bf4d76c22dd018c41e19be25e2f821f63c2046085d0af30d8b4212ea0f3f9943be1c14fb2d2a944551107cd2bbf8dda5bf258957325f06277036282977db4575b0deaa\nB = -378e1be10a57e03b197bc2b1287d643ba6d89da4bf6a6170816691fb6529c602eced237863ee39659be3729825f032a57eb5de0a87b0894d1a1244523e85b6f50a3d9976dbb038490e46\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 658169197ddd0bfae101c10c3e6a2b10dbb456048e81160b47b197fef439b1e0ed710399cfc80ead8e436f1c0399064f92da50afc335847515686e055fc7bcc0ca721184435955b896b0af4f4d96672ebed2f154538d49fa507b945c0a6ae926793751231980274213c80046666c28ada213a2f87509d1466b8d1b2122e93f8\nA = 49136d37ae8f3da71a6114327833e8aaf3dc8b5a9a27e9d04c953988456e525263f86ba94397321c2093803b789f8db3ed7cdba19c4b796500b979e02952e1625246f8e977e01fccc133f94cb22832c\nB = 1dca005663385fc00b4fd58c73adc7589d15ddbcb8cb2fba03a737a320c447a2b21e576ceda73811a31d8277883fd31e22f776bff3261a098ecf8f40f2855b0c723d1265eeafb43f85323e3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a49fc8084f3e780537b4038bb769b8db3653a3315298a99c2ede6739a1732a636e9787f2e8b09d0b9bea08fac43cccca71a315e6f4a7d6417d171b4693dbdbee8cd9f95be0847ffd40ff027267125d67b89737e1d0365bef6c4429504d13cd8ddc7810f456d6293c0c57c14a307b94010d79d5c13b92a907f923966fd3c5c8ea\nA = 1e7d8de2061cca59d1cc19b356a8fcdf2ccf917e0d81598f014167c5a8de027ccfc8f2cb8c37c396ebaac83ba862c146bb2d551d10ce03de9528f97725804e8a6de57b9d9da811200604c2a032462b6ac1\nB = -e38592f3acd75b575f64ced439d5ef2377d21c61bc70625639b01bf755fa2c6de803ce155744993493debcd4de40860bbfcee86d0b117d7f8c3f8ace68b67cb6fe7a81a145535553896424f7a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5a99c8a6afaa97d8e7d84f4899803c7786b1bfd2ecabdbfbb3bbb92247ff91ac213a72f6d23c24699d60babe91a7d9cea751e686c027fa1c954474fa5680f0059118426c71299462b11de5f2817d190599cc4b352df4d2e80605f9ad1e32eb13712d3027a2b6a19d52151e37e7fa057d8fe59dfc8a943a42a1756a38f103a75c\nA = -7df29221e6a102e32757c18f87927cdc90ecb012ab0557e0ab855daba832d76ddf595b9c5a62988ca968b64fd5bba2a147a5991810c17cae7edfde38bdbb7e13a1fe5206724c05a9fc9276c8d4e503a860c7\nB = 5c586d1aff7dafea3b8ee42e0e8854712c95385374b5bd1fc8ec41a72b296e070940c4160509a4a1699a678533ff3d12299338fc441b0f01e29a48677bfc5aebc644555285756e97c74e1af6aaa8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 21fd2d881b6a52332dceea42664aeae1ca110512c13bb33e25ba4ec0f39f80eb73b1fa0834c998c23a2453dbff971eadb183c51a30ba78d593f23be9cb6b2b33a554ef31e4a36e0314fc2ec889f18debb956b89d1bf8172553271bd56d89ed0b30abb70e68abaa2c76f73cd5a3de93433747d09c845b5f8843f9fdf9f6c975c8\nA = -19fe3bdddcf08190a037768b77666de803ca4f7f0d7dbe6aaaf334a486dd0da7ca024d1b3d", + "f11e0406b0326595a171be30b04574c1a7d04f4d2ccd334663690fd20e4fd168386280510a00a70c1a11e99483048\nB = -33b2400173c057980b0e0cfabbda1a5cb5b83b7ae80708c199f28142237f04b071c6eeb63d42e80eec04b76152250c9e4d4c4f19a048cb9815dce6e66710fad1d27494db5c31d9af37d2aa779d12d7f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1c45cfacf30682a876cfe253f05b393a2cd4dc065ce73126508ce897a99a723cf5145187643ee62d746f6edf70269ddce3c348a1432316286a648ee9ac31ef87feb14f25c42f2dfc2e84bb5bdb4ec0124e249c526c55ff2cd0ae938555c5f86d856eb181572ed01dc045f1ababa52d249e56aba0ecccda905d7d1e64bf89bfe8\nA = 6a40d948eac2fe5bf6db15d7f6b89fdc0712e32d39a881c21859e8f7722391ce05973efc7c40e2c0d7f56c217d8a986bfdb08bf87bc0435873cfe4d01967c46f7d39464bec411d0369f6f5d1d83f42596fa47451d\nB = 12529775e8253ba220d890d4912fb95f91e4edb59610e889431208b6bb42b089cf2aaa12ff9ff98c2482e7f4cbf35b22d15fa28aa288217bf766e937a706fe1e600143087b0a67f668cb7b762c9b9f38c0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3b3b08e8eda8be3918bf648227eb0d569dd898729d9cd54deb32b1a1dc69cf7b2c4184c8ae9641f0f75950df263a5e236f428ca86244e617b14a04edd0f31c02bd4d84f25bacfcd4a2786825f0361251475eb6c7e99020dfee4298a1f1bc260d4e364a332bc6f651dde7ce5026dbeb0e5aa75ee98874da54c7930108ad28e3a0\nA = 149d36918fffa682cf90c4d3f3d48e6408e7ddcbeb44e78b9cc7fbb08108f65215761a61d79f37ec8f67cc51e0a9b4bcb3834b0ebcf6734985153f29a2778473b80147eddc813b4fbeb98843f5c1ae6cea68f88dbb4c\nB = -ca87f66182e271a69c0964eda92a009d438078b584c3eede28ce1a501838c5f497186d305c09922f32ba858fb55f2a0dbfc9cd0f93b789c1f800cf092726d6d33db19e4f26c7dfca69b83925db14544ebfe2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b199655160d88b6b4157ada0e5675f82b33b5592408bb57c46e2f7d8791bfccaa51436dc3b772b83e907c20ce7edc2835ce96595b78c0647d244e9bad6f4184e0003eb0899e7a47ba0be888b9bf795eba95e5073a85c4d20416fcd4a8d4e1e16b403deb38845fb8bf9e9264d68807acf02d579e8cd104cf2bd555e6cf73d0450\nA = -70ccbb73e33a7cec30ef2071f3b1f2e008e70fd6d00fe8b7aa4b9146fc6d0549c57d984cd014c7e0a4ed6d33376998b7c2c9778fb9580d8ca4ba795c88612721c153c186740c58df3fa63b6cf7a4de76e049217218c05c\nB = 6cf4168d44a8da8e8446b4420466fefbdeeaf9623a40e10b77547687b25f36916f2c18cf6060c03b3b40e0959479f6aad5e44dcff0ba799262ef53e280f4a7f667d262d472b2e573265774deb5ff8f25dc1822b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6ff91af444c61d2e2fe8ad73bdc5377d5becd55074eb60f0f98eca3d8f4be8c02f196b3afea12c36f78b78ae6a5ab677ffb7d9c0bd58987cca816affe468c7fb4b56055f5d2326532d6ed1c00ca2d052ecd103994e8929bce04e067082b4ded7e1973566f99c514b4e0d95b9a8a931ef4f6355066940990fead70208a63841f8\nA = -1c924bea12ad6f8b65abd1796e381fee2cfbec15138191bc22d57165928794bb080c83878fa5fd19a5d657b2fa91165459966f50aabf19440f7d75f027b32e999ff4d3f7a7ce878fe0f33a847d644d86ca19713ca9968d97c\nB = -3abd4b281b8f25f5957d1f2fde904457d49a3a7eeceada26b454ceb4ae0e879135d376571f08b5038b7b3d73a9a9fecbe265b72375756a715a523ba66737085e5ef7a4ad988155adc93eadd5d95a0faea56914983b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b9076229b1a1241e8b4da3fe143ac31d060785be6ac1e841c2fa9683d2bacff2e2b5dbac33f58b0b1718ad2053c37ee55ea54a9d258ddd8930d2784852844d85db24e4721762839a5c73cfe588efedc8932ccfa585e1b5975083919be9e32a86dbdf5cef84d3d4b2ccaf7a006c0cadca1e35fff2da9da7d7e779494d8f85bf4c\nA = 75eb0fe6c07559c2b0c7b2acd7d29b5798f6c4cda64a504ebabdf54bdc773ab28b218f0defc040016178958d5561796230b71edf49bbdcbd3f14494859843c8ca7a0f777cb05827f2839f3982832f4f3e3c5e50af17ecebbbc3\nB = 1b8aa718d61447003fdbaa748a9d86befdd2675a677cf34a1be7c81e4577f665d71135a8a243976a4f6ffa1636695567bde522f8fb1948033a7e0941f833d827e957781cb4349a08c6be418befc8959960fd5fc1b288c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9df82b7c34ca97a3a5d4efa28d5ed4f35484914dd73af9090c4bb31ea3496ece8ec650f4e7b07dc779c97e597e76e43cdadbfc6e72b61ea718c073be1cd204f8ad2bad0df1e530e75705f3d3dc285e9d793c8d42f04dc20773d3fcda8ef3ac1cb10d33d20a91add0358ab8658f49d2fe51d0d2d72684e31c0eef85e5695bb4b4\nA = 1fc2a171445ee6add5c2e4d29e50b91d83338f8d63c111e4d3e95f16d2a33be02bef24dcc3d6ce6bb8f1ef980dbf8fed409a0232c0566153014eef840aff58ed8c33e8d463d408f93e2f5381a26fdea63676c4e5397eba1d39f928\nB = -bdac7a177c77451104852bb99004ce8e617036906667258d85adcbe8cda21ab7d03aa7dcf62cb210a9db8fc750c7e1ad290b35473be0fd607fcdc686de0b78fd9f258f5b25e2ed43c2ad1a38859f882b9f6b293dc258659\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bd9f3d2e8a1086b177698f87a9860e3a5f030e04a0bf4ee9436ac55e005bda01ff4ac662cb85d39e98a41c723ae542a83a936c3bd0280c6801ffda080ec0aa4230b45dcd0bc5eb41cfcf272028bce3572847637a92d1543bb2b8408e880f5b776e1cf14fa28d15cfb584f025596ff10c9f091c837a3aa622d9e5c856db8ac207\nA = -7fd5357cbee7c5e31fb62ad03bd47b705b574d915200fc7f1013d836b9cb683db020b152ae9464de6aeb8baf14999ac7025dde6173fae6ade325c60ec310eff6dc4130a8efffb15ddae90d760cb7f76a27d0368175d4a44a22f7f223\nB = 5894a0223e4aafe4efd4572752fbde4952c8b09cdfc35137e7e6ed650f8fdcfce9de673853dbf73730b159b2656047e69377d7c5025a6b346fb08831e64bc8bc34b75765012460d8135a4f7a0f41d768fb85abf17f5e2f5c3f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2c61867bca70e8662c7e5435a5aec020faae86fb079b992bf49d8497fc5f96abbd38a6f04f6ca8510e0160e546b3f68b7baef4ef0f404e881771cc12ec5ed3e3787c2d2ad6bb957cc59f8d56f0afb4bea49cb671cb42f4e8a0ee1dfadb6fa14f84a5b3269dd33e20d658ea4cc39499c7a39a4b5650ad7018d32f97954610f676\nA = -1bf5ae15f24c7c14eb59605136a3f679f303cd5b81e4a27465281d17715afdc2c231d7ccbc59f80ad176f4e0326eb757b52e3695e27c6776d7936da47e3a8a904f735b151422029535045ef489e61ec93f02e6d588491c8dad1cc311f52\nB = -3238dcafb85ce557036d19e42e7e7e473de9f9da6f920e18845dd010546868d2652decc94596cd2c36bd16b02c02559892b9f573bf21ab18c3c75591413d046b385d08aa66d849ab8adc9fbf788e837b047a7ce2b9c63f7fbd263\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c1d04b831b712d0619db462c3f3fb5973f5984e9a48493ff273a5abe17a548e185d751628899e2851e425a7d4b2c72d4d908dc813cd122b8f497e08e299dca9166f19752ff8cd9840a70155ed9e8c063a3840838b3679f96f1cd5f1cbf0e037d222029e02769dce7fdaea0bbb5417f85497d77c76a387c6b970eac15dcd128ba\nA = 7aeb60c134e84f289e419b74f99a5ce5b4aed5fc630d5d591ac7643251ad32d6ca7f052fdf8857f67138262d221de644140e9018f7b84879d74883f8f251303f65e06bb52246ec6a912772cb698b47de41c1826ddd065359f6b9f1ccb0cdf\nB = 17f81e53d9fa6201e4d3eeebb32267929cd5258d10f053e7c021c4afd17094f8ecf433b1ca752f8740f6d6bd84f801b1b9fd6", + "4bc4787b9ae5e5aba0b4318a63dfe27e92d5a3ade192af7563c74c9d6006ae7701240efdd6021a83cf6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = aef89874854ed34deae1b77286f9cb0e3017e3ae77fe050bb244acf4f30dc03504c73c1a4d44b769709bdb53811a5d0f8a76a08e6a66fc2cc4e98537ad6a8049f02494305b89a49a55e71fcc3f5fc42d6b478456ada9b19ec0a03f5ccfac5538c0040092771660312be5e51996073ff1a506d7460c57d54e10dc2991c028606a\nA = 18d3af14bbffbfcabdaabe44074b407d69abdd80a6eaa5954f0e45fac85af7ced1715c78da872f7a8fabaad3207e31f12b7195cdb25abef0a1e54d3b13349d997f207fe130d7985e2033cfec899a0af310c9827749cd22bd062eb0b1faa254de\nB = -85a7d9f08a60031e689b0e611d7f7f46e1178eaa2e6459602e738990c77f4d3783ac43fc04d53504cf67fccbeb02f9846756f8e32fa4a9316b6d3b45f644254077bef096a72bcff17ffa17070a4355121cc5daa2f782fc0d0bb48101db\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 14a85edc6297763547702c212b1a8274b8f85d53ef35cd1b01ed51039bbe030d0a1b9626ae2f571a43f1224d723847a1c6708f2238f6f6fd75db6656e6c703a5acb57f69717efe8ed58a3713ba2720d8c001d026d83de0ce5e24b67c41daacedaadfe404aaa9b672f00562e6901fbd0710c4303fec41ee3338100beb36c9b1ed\nA = -44414ec207060d105f599b9a66aafecc5b232b55214c1a5e1922f6b59439b3ff77cd3a327bce4f7406871196b90350e6dca9aae147ce03027dc4de7563c734f111d95171f489105de5ca80047cfa43f7e932917b816ba7d41fb95b4106745d700f\nB = 45f2cea1b9b75880ac3ec206740cfe0ecceb488c9155cfacf5885a8cb49be78af8cf221ff8de2328f4880479c031f830a3c9eaebfd83f7de501b7c5cde03c4720c56a676d331b2a13c4689a2e34a43fc11f62825b8776e75d31225ca7ff65\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7670c1e2e141d8f8f5466de8ae2e0ba2eb3eb7634699eab8415d3a37f8df291d00def88361e9fb64a2f116433dac3ac2764fd62f3201dce4e48a3b7019e5465f82241ffda29d5eb0462fde74dea3168f8993ccd4d090b9c31a5a6cd7e05f725bbc89479836b89379b422250ab049f31c860110df5ed69089716877fb0ad7b0dc\nA = -15b4a2f808a85a5bd466a342c4853c04ac0ab73f8e53a4a0477f73dfeb8d7a911ab2eb5d3d192b9b084d0e38db491148947c66f838aa5f460c37341b129137614259efa531c0e6ffdf163ec6851737037a5299060418d96da035e6f583e6ba79d0414\nB = -3e94fdf22004384f7881875b1d8f58019ed8afb1b6a31f5d591e77b0998f3100b34174d6f3466da44b4c7fc8b92ccc5679c26c146b704198a65a88554d24291adcf897bd758a035361f671a82972b5962002c6a828792980f86a64547165327f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 35b49beccd8d2010a8d777c1ff69e28e01a1bb78c6466e717f0a934bb62f9bbcec5ed29f9cd2c14d240a6c33b28c986eb9c8912a4927605532483dcfd31a50876e1819f3d7a0f49bd276ced5c4110470244fca52d2611ed7e31cd8b73e749aa70743b39e92810b3b52320342a65cad3180f6e2966059d15f79e5574348f5f66c\nA = 6fd078e3cbcda6a71a710e99204da640edc71a65974fc765999a74ab50a0e4b090d57ed0ee869c8da2cf694b6fab56e87c4af62fbe73eb8890bc066ec3460beba04dac3b8fae7e4f316e8f954c6e8d934e946dfdc9f4cde0f26bb3d40d5c444b03bfc65\nB = 14d8041a3b83468d2f44f150ad8d8d0a1a22035d630f2a17b70d5c3d557d3abc7e4d753e1ebfb3a3ba465520b84746073d211a67e079ec7f47c2cff9c06da69bb5cbafcb6cabe7e0018867c42e07931d6797d4499463e3cf786c6d5d6c8cbd600d8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2f6e0fed8a9720fbd83ce950d7545d2c6d5b271582194570424f90309227a51777cac974bca0ad3c1289ceb91cf75af73b0645cc20d71e7789144876b8c1bdd550328d9907accc316189e8ad81310848cddd2dbe362c9398d814a048f93f9368fdbec0f19ab87ad2a59d4066d738c3da3cb71d4716f2cd2336ad35ea1438276c\nA = 14bda9e4aac85b0ab7abece728f61450b7779d3b5fb83be813758e742d2ad76597f132aed91e20a75c554f0d61ec4dd118eb733d04942b2548b1efdb4dd22fdb543d9bc1e4bf0574ae2cb2c46fb98cc4835b6a074d6df1a3bc5443beabdc784d542e3349ad\nB = -efd765f8ffd72d041ac3244078b8dc4482233e9411b289cbc2cfc26fed2cf28e286835010438ddc9e7021ceb098b10c68bcc4732608ec1f4052df9362176ee14812bbf09ccf7c2882714ecbbf92bbff61c06e9dc35a368208a05dde949fa2cd091ce0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1f0c436379f6dff55a59093ff2a0626a9b959e3e3e59365afc33c7a7893f04bca863ec910c446957baa8de4e35a1f4e9c4a776ef41b053f03b775f327eb7e5fbe68bbb478aa4339ae703ee4b573d6931e47e09271d40239d527fe77098a7fbe519f5eda1f26dd6a7d0ee6833efe37187d8a85844690fecf9fdc3a4d80b921130\nA = -51eb34de29ba24d2b1fbeb0a1c324f4ebc69cda2dff971a315c0c2775d988b03ca29891ed0790f3dd507a1d26ead461dade9284613e45df338dd83aebfb66050465d8aee554970b43f7d4e0428e1512289fa1f9b23867b67095c455b66d536b91207b749189c\nB = 55259a1122eb7eb611a69118d3d42c2f05dd228d71c0e1e42ae3a8d3d180a95b74150d844e916ac85105805126e4b995f2ed1cd3fcdf28e1fd241dbe3125dfb3e4d90556256eb513a2f7c9b596719c83b26931d92bfd3573560e8bf054138f5d6b9cde72\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = ac321a272d2206df4dcd6ed8ca194a1049c1e3a20bf325fa44809d302170f850721c077bb5d792f86f7ab03ca259567397cc2fa1429771190bb632ac2c92d3fccf6e05e13cd33149994cda5f9c57da155439663f6a13c66f9da553f5038fb92fdba186ed9ca04b8ec87cba4c5a68c8edeedb94e38a6dbe293340dee1a4ecc768\nA = -19ac99d7d51456b00a193b3b04693c7e5436e05763f0154768db078ea5111cfe9eda3451091af213b9c8cc649d341de66c12ab2803ea39655d3d7de182a77355ca444c5d2778f791d39952a7a11839e497f5dfd8a703df49ec4d7628bfc25a992e94a6477e6be39\nB = -286d1d436f113308be594f0f43d7a05120639152b7e2f93058cf602cbdbc016512bfd23f7aa937fb358b7b602d15998ecc150f2b9224c58527c0c1267739e065e24236771e2c683957871637468181e6e896b513569bd004b9845f0f0e4c26a5ca123365e1c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3466804a1b7d1af8b6060aa93a4c325d9cadb33ebcc8bd991f9e44cc2cca8918411efeed0f005790d649382ec40278c8cff903cf3db177d24466c58cf6a56ffc14e595c36bfefaa2327d37f616b1466eb702f5c49170598bc361d892e18051b8233dbc5b3fd6832befd9a995bcef3b0f3beda6efaf09f7306ec203172e78264f\nA = 6710c19330d3f974fc377e28039e0c0ee0a558621fd67fe724c326537c18c66dc5eec60980e07d401ad5556a05688d2dbe7b271f9d5eda3032bf7cb7c420e7b5d65a195bc037090b6fe83064ac3731624ce2baaaa62a6eb07156ca12ee51d4321988026cff573ede9\nB = 137ca18f47a151363a3e8c52dcf024262ba525ec8852e8e406f460fffc2cf88f1999b17a5821849317fcd84d09c88ebb6eb0340120f113d7ca5fbd91c6a40cd790bce7b422552cc0cfd2a6417add2501db1667f2802e5d0f4df824adbd033a90a155cebfbe0b53\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6f248a70b2cddd9627b32fbd130f05a604866799365f94d97f1eb582b28192959692a870be7c2614536a8de84cd8c1364a75a3927ef9dddbb8c6c87dbf526f2d3a7916384f2daed96002831173fa4a51863c28b4378f99b1b201010581d5eabd66ad1e328cc4e647bf5e0588bb775e130b4a4d029eeeeb5852c5742862ddbc3e\nA = 1f014cdd87cb33ffee623cf454edf2c476e91df279b4f0879637eb6e8e5ccab305186de67585595d34ebc195fb15", + "0408c4620cf6c7a0b0d9695ba0e0e1d7552ca7d0be3dd678b1cce2beedd11939891a6804770f1c843e16dc2ea6aa8e4043940c37fd3d950caa122845\nB = -8d8d9dedc80994fc5db04d8c935301e47054250fea9020bde8d5fef01f2307cbf458d5afef5210a369c396287c5eb453637a2d721085af3de0d75a5dfb5dfd22fde3b229d438439af7b296b9e68ffc982efc6c825556c52a735f8be12a214a06c4270824d5268fb6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a35ff7e232f047e575b200b9fc4c9253de6ac04c612b8a82c275a951075eace5e7d6664fe8f78301d554cebe7b996c1f4ec3ca59d8d12d7196eb3909223de94c220f0445d24233534af1c93433b05c5924799d2c781fdb88c4537bb8d442e6bf76b2d966827bfb4f40378a3f135103513da056bc0d375b1339561700d15a0227\nA = -58346cc8a9a1e5b8babaed8e7f59415388e0db654ea7cd465d96781c57faae7a8af8e7578e46f3a8de7bd1027188e1cc32fd1c0d60be24fa3289a12cd822a6c9a77dcf8799624856c27ba88fbdb047473274e651760581b44457ed048cf76c166d38bb9b2afd3416ac7e45\nB = 61951a16dc6466a9fabae99df29b7229f1ab96b476092dca1e4f8fc8e7404e2fba56ee66486d1f27f89bb3f86f271307228d7d6cbcff943961e177300b6acec1eeb46af1c5725f745a2d2af0fd9642f57a09c9ce6742114be0aa6e939e638bd5c7a92a7c206b2d36e35\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 90b441d8277eb1ed454964acf567067925881b5db0b446a7d554dc61ae87ff979bfb0e58ca1706123453e62ce31284a5a2db1228d259e27abc7fb5cc5848dbeb9a6808fa1b4afa844ab39b652abc41423c2833e1209a1674db518b6df7ebae315dd7f416df54e73088762ef64cc2cd0a08b1cb01c49d9299d149cbe84145a55c\nA = -1ebb693ea7d18e0ff4a9a51124ebb78bfa3a4635b75a6387e9fc745a2325409f927324d1289be8a4f5cf2d5c04adc7ead20564f97e453287f03e5ab59a6133584f970446652d05a131d7d382c47b7cb97580ef6710a532dd4f5a0369dd3db500ae5a3c5efb587cf0cd2638382\nB = -3916ebc4653e7d6e0a4f1e234d765d41e9e948b5acd7ebc73cb595559c1b20b037a3c8da0a7aebfa5fd327bdcc922551cdb8db3fb0a581fa0620ca2d2559ccde3ebc44542b4d80926d061e2a35c08c09547e0cd587c396ff2959ee93ea64b1e6b7e2b624cdf445988e1f42\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3ac61c3a028f4a2df6645acbd36818a2f76a3229d229ce22471760807585a909727411e8b68bfa4e76adc459409a101a1ce83900d46918e8d0903a163de87c07bbafbd60c7f536a62c59370ea53b6cea4384345343146bbf529334b4201ebdc7585b6e5eee42696400c9be9f496406a4eb51d2fd1b40466224f1752b181774ad\nA = 5a16d5fb9047949684b80805e5d962bdb939d0d0368b48517a2a826679c37ee0ded4fa83e657192d9ae84294e450f7e2f2773d1f13395169582cbf95860891b9fdf8f3240a16aadd1198e884f22b2718219d478e2410fd4bb98ea534a3626201959af099fa55488f5390791bcc7\nB = 1f67066dd06ed4a49cb556dc2fce22814754885a7cf6c13915d974b46b0e6269c0fafd688f45ed2deeb026a7cbb772c080dfd577d21ed2c81e50e7537a70dd550eb94fcdf626500040da88c43dabce13c82a93769a9e0ef66a471661292dfd3b3af07169e2dc909e43678400b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7087dd62eed6ccffc7e1370cca9444dccc4ff160458941aa9f49dec1a2e9ecce4cf50ac2daf06994c5010cf225cc92238cd60e1aed9edb2befb0fb354ffdde94ef5e8ad0415bc95851d59095a5c4850ec52a74c78eab58309f395d3078dc481feb9d30bcd9f113af7a01611b94d085e32193dec738a64c5fe9bdfbf5dbc98cda\nA = 13596eeefbf06e9ead8d883113d8ae6cc3da8b6fa13ab66681db5a9c083ef9e49d905ec19c39b149cc09452eea0446b29cc92d4e865e6f681827336945282fa6b276ef552363229a976c503b822e6e4a9862d3fb30dd0c3627ccb97a7046a6a679050a39166388a9daad5ec5555dbf\nB = -a4e574363f2e5982cc087b38110d257019962fc166c2d6e6d396220bb308a8a0dc7d90c5cb2ab85faa19b07ed7dc11eae9bf2abde0a5fed279e77a717b43d35e70fec4e18445e37741262d0b0c20dc4375371d87d839d39934f1dc41122e815f3f37352d04d0cf514738b351f02\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8495eeee238164082240ae1db1e3c1e36fb6621e6b714c9de914f9de8a587d7106b8dc5214f7c60c0ee231d7441e03cc26462e71adf8e29772ac95d0395722d2756f9f64daa8ed41d7ce824a572d7f9fd419112ae823b5b48b8aaae09fe093e9ed05918c4ec88ab159890910837ad0691849b44be95993682b2da2b124de39ec\nA = -403f21e1a7911806747bb78a4f20c4e6572d49c6c4ce071db0c8c91ee985e68a16e60093e4628414b2673d25c9f13c4c43600633af95017e3846512197c9515aaf9953570ce5861620716b3d80eae7de0f033772fba82652484cb3ce7cc189d1fafb14e044e07a88da302547f2e623d8\nB = 689d1b4a968b7c00082ae3a29c8571f826c4630c947a7767fe4a71af43a5de84db9b5baec0980eafd0019e09de1b5c56173ede68c9a6acf260bef3d9a03f4c83a33106c94ca7e1a8615b3553088d1d05a62ddab0f1e5a126df5d960f67e3b92981022e1f0358c7970bb2fd5dce7a7c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 397df584bcd3b2e1ec7ed89de624e9d104bd6812901e38c5740755ce91bd54155c0b624c590ded199590be5d98bd1ad4acee56a62d05d6b5fdd1ade12f7db8e3eb08c4a5996450cc1204be7ba61b768af0efd563ea478033324731e24fedada1ad6e564238c891494e85ded4feb2165fda22f75bf120856034a9206511885fd5\nA = -19cc480d1e07523bac502872a971d78bb26955c5453386f5d51767150e229daad3ab2dc85e0fa0cf6e72389391fe627fd2d9f263f105508642eae5a095ec4d88545dc9d0a2c436907460e1ea7db174673000eb2e0b60d57163ced261bd0f6cd8ce54133cfa10591f1fd27996353110060cf\nB = -39c45512fc7c9620194fb7ad22abea8f6dbff4a137dc4523115ad7e262934143cf1f320892f8c097a400d4099e787ea7041d0d69b6269d191fcdc8ea28340ecacab71058cb39a9c7362c848826b35ab560c27113fe53c497ca452397891c81365b6e7f07f916d47961e50b8c7c5cab38f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 263ab04c98efac12210beb66b13fec7c260c5b1cbc20cd732a511fb3786b917a617d6622847f4eed70f25982ef5d0b0d13848c62dcf447e3a1d491f4c80e69cec03cd318f6f93134d582210bfa81c1790562053a71091333348c6624d4d793fd6ef971d284a4ebf0be0771efad302015abfaf3edba017907f10ea14a46d9fdc4\nA = 7a354753e39b9ad1c0ad6b65575fc7247487f3ea320fa82d1d333ba8dd5d0ff925331994a6961c9c603be5775ef1842159551f0bfb34920b93d90ca60e6abd514650f77ee8ffff2bac0eecd0fe8ea0fffc6ed0285c9f3c3cfaacf338043975457d62f9c8dda8cce1e99f34529435016fe2ed4\nB = 1a4384f9620567c698ced05870b4dae983d8f0df6aec888353f9dd6ac8ad54340c3ba8346bfa47bac38897f3963fce972f6d55f3407ae03f5c7637be1a34e483e50dcc27148b76ef079f117104162beb191d146ec828ad5c5bde5ee1683a031d554c276d837bf1f2f622cd11baabce10212e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 91cf4d1899e170bf75dda0d51a6481f79eb94c333b876382c9d04681073e949191223926523f6531f0a45765d7f382221eaa080d7bd05a3c19220ebe18802b15d8009714e8e4e9872223049622ca02040eb041707c7e525f698cc361847c66fe3673a72e4d701466bc374f55fa5437216eb59375c0e2c4f7020149d0118ea72a\nA = 12f35c48024e8271e8f9a60a48b5a214bfb6595a837c041b230e6ac87a4c1d4b3f93a2d3a193c750c9857c8627d0f7c454d6c4f224dbf14a865eb83e990b1d9b8bfb729b8d3dedbbe9c95032e4d60676c2baa2aabafa698392590add3b83b521a7a5e7d6f8af207e44ebecd735374acd01ef5822\nB = -8fc18f92c0613d085cf3ee6f586b39b99ecca864bcbe60fffc63c585e5613df68f3534ad46e244916b1f9188507a3692526c9e403b8e93480b0a5a6297f65215f1a5d8e20631a9d559fa1acc15a98c9397761ce18903f393b10444ba51bc92ac44df90d4cf0852da9d75902230c6de6f26", + "dfdb\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9af562a7b61c6c84c91bf979f32ba5d246d2ee2050f07ec2dd5cb3f9496bd37c3922ecb2b5b17085a13e93ab2dac6022077cc18c621cce3a2d2247e5e89de8692a36f596e5dc7a6969a4f3ff0d1580eed380e6550c6218c1938caa2b7ab401ae6f520063c811088504d60a19da3b5018d640ab8d340f35d1337a2ede8bc64bf0\nA = -63bc10b8fbcb391dea305fe61b404d3bebd035514a812d0e1d38daa3d67f9f1bb8f02d2979270cb9147aa51d66ca73d4b5787e472456a13fbe0d568e92b622439d33ad3c357a56dd26806ebda7b3bb592385ca5dba7e5eb5d85eed0a1746441e8d56e22decdbf8f4296e30d222da5af17c427e832b\nB = 57a602bbdefcdd00f42ed1e2cbde2ba858d171804da56b0ac87081424ad1569df1308fee7c9ed349eb496d5409c4c46921f09ff0830bc9f57e920e17df16523598fd90314141955ddb84a1522ff3ebfa812cfeb6670525123476a739f64ebe6a5f1fc805a880f8e5a71b908c483a121b38d05cc2c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b395c9f264172a3653af6637e72c4c8e564d1ce68032a5d761bf546e0c4b51b33cb026bb4256fa639ae98e54e5ff7d8921ae411497272b53d97c2c44b5b9ecc5aba43dde201f64f1d033056f19ceb0cbd04decb486a1d07ab1c64fd213d7eb6db9cd11efd743462e137f368acc4ca0b49a7f85587bbb5ede4be1616889e2699d\nA = -1e71df5f04001f6468c3a192086bda948aedd19c5da9a5286856f30524238d95b0ae71940f2af123315ab5d2fc61964d3e970d5858b7c1a78d0f2cfd10cba7ba4830a8c19a09b59794ca5d7da32cd8376b5ab06079b51cd9819c0021ea41a9e43aee147befdbb17a92cac7c7767705fdd908bcd291fbb\nB = -394c187308320ba1b14d91d75b8ff993dfd57f9c84e8185f12bf9924e046629ffcd7174879f9925bb643988259cbe9dc9277fa83a25012f91159b012f1964aefddd5a94ac6c2a55a22bbae93085dee079f84cea1d53dc4771901db9a3db5a14eb17c25aaf5377e2beaff6276cbce7cee97a9b8f32737\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6602ce0fb5002eca37e85b60cc871b7b2eed13d38c20a37a6e0886ee4814f3ce2515f8714c67ad81e8c3abf6a00464e6a51b15e55b6c11296ada43cf459e15915026d3260cce8fb796241fc2b0bdd2b65ec04bee3b7ab6626e10597f3b13b43d16c34afd5b43a219917626c88b24c6f8392bde1b2e65a50b7f1a8dc5eb096702\nA = 4855ce75a3d7dbb72a257f6291e9f6ccc158647aeb2f8beb3e8fb32f6f59af1a46617b77440798562d6f58bfe826d3ea7dd28daee8f5162d7d24ae6c24c2deb2669b15898689ca789e2005903f3a94e991e7d3c8f3ae6181029d959bb15e71d7ba94d2dfd3ddd10f6fc49a65798b5f6ffd64682c78b5d91\nB = 15b3e9992aa3f042fd58ff97a8c04aaebf46b75fdc38caa9224394a1805cc26e4311bfb498d5a04d19396e98d11c8810620979362df82b23a115fc1711b57c7a56b8408e2682a2edca36cf9311addfedd2d0889a78cc1ab170d1379245de6f1f6f4db815fea9130463dfe5283f195e6e81486a1d39634aa\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6a81ccd82f00d829bac186fb38b85097d52afa3ca83a026856bb83f94d6af6f6c6f3141d433f8fc159d11397df8d2f44c769f255cf8148249d8e9fc4f59ec3bc8e804d7d5189e71e20b8d0e540b59a2854ddd7feeebda5a95f17605e8bd5f311a63cc2e4ce23a51229d0a49ca04982c1bff79c201de6cc6150b690c98106a39c\nA = 1f1589c9b5ad9d878631cb03c23ea7e94680220856285668838452a63b726e01709588b38e578da8a4845aa5cc2e4723beafa4f81a1a2e463f67d9a3e432de7064ba8bfcb943cd9efb0e5a136649cdcf5e85a667917075804991b997f318752304f4946d69abf161625ed0c03bf9abeb4ef28034f818e2a643\nB = -909dc7fcbd27d0bf7d6a3d0e2937ce725b5cca0acf78c103d633206cb431e2e2c785aea4bfe2042df32417143de76b71d21587112f36d067f878e556b94ef63d59a07d19647593efdba7f3f5324d64c55f93a283a0dafe080167f6576053f9beb326994f4a1d53e18e3f3e770e69450bb70f276d128e48ecc\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 69139f2e10726f83300505d15dcbad5b5f284d1c06789181683b7b8caf35dff063dfa4968c35facf32a3628dcfc19b3fa4c30ba0e030b06773832a2631529fe0c0c402e05a0c4e9446a8b6c22754c70ef540f90d903d83a2e3592169ce6b5edf939ac5ff25b8bd48aa2425321602a9571661a1109e275a3b3039ff0c2f430b18\nA = -5d02cf3969bff8789850ac898c00fcb3ff1fc49a22cb243ad18703bb8fae25f83502bcdd885417fe46e8237fd0b444712c4fdb8f4972dbf9278a83eb305efc7a8210ce55167c069d1c4136a9b66d0c4dfadbf036c079d12aa082fbb42bfb0098006136a61f3da43aba3d3bcf2f5ac2d7884caddd0cfc28681d33\nB = 50b369234d993721288662d83298d99b9052a0a66336a5a31b76dfb20ec2b5be3aa76f78b2c17c63d78402a15aacb585be5c8d2e7083145e316e71e111fd34f5c79363c4591c247b1a94b20ee042d840c42a3001d6c8dc7cc1e1348e0e3ea8c6551f9d24af2dc2d0c38a54ef065ff048b148ce4f11ed2b549c50\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 87de406a6c957e85c759f8ff684023a0f98e93ad4ffcbc6fb0038c7a7ceed2486f15f36555d286338aab3283aef677118f7cc3f88a7ff0ac9fed31da6786ce895c3c08d3edb652bbc9ac2b44c4cd24ad281ca3a8e8e6e4d730f4f0c25487cfc1b2afe222934eca8b1e1572780dcc149422a88eeb1bf31065c929685a0a97ac3a\nA = -1878e0497aa1c2942a2e6956957c876dac73c4bdbf42bc92498f29a006bc92f788c24a4624b87324a7c8aedc6b2c0c8a1a442aa91557aed9bf2c02b6664979e8a9a21330dd839f4ba8f84515fa6f7db9287f7c20f31732b98fc09ee7796dc524870dc35851814bc57e1a8ac49d8935fea04bb08b8760df33a98149b\nB = -32f4e94bd073cf3f70810d9af7a873996a0510109bc6fdebb855f27dcd012c59507491152d30849d75f95dd868992c6fbbf29b1d899cfd401e9e7f4e0436732cb4cc9e6a6d6b0cb63fb0bee21e422b7f7b7b14dc5d2b6d10447fc4add390fd3c8e7b06f1d9b181adfa8d04459ed051bbdc9666623b00e3871e597be\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b456ccf9d066dcf4247a21c7f3820e324ac9cf004cecf8dd1f6c3aa40c2a33e24c423e97190fc71bb9fec21d36c5a687065a7877237a2a05e64cabfb3b20bfff0b1f5ef2e9adb7edcd7140d1047b0919a2c770579ab44a08e5ad9f63a06f90ec7d5885b91de5e524b2e187937609b4b81d40a0b33e31a48d7b9868add75286a6\nA = 6c484e3c6b530dcd3644b19fee66c41c7c2c1dbcde574d87ee13cabef9dccbe5b41e25c32c6a56df23f2e87176afd28249e5fcb918723707fca94d7e2c9623a3493d395db802a1b49d550f52c29666f785652fe81afcab00a60a5b50cbf523cd13dfa06d5a5b0809c68ff7264a2cb35b8d52284172c62ee658e8417e6\nB = 1b4fc753d0530bd07094bae09a02b1ea684fb4e8519086b1e2ed9d59af011f61d1b94ffca6f354a5b428417b328bb1e8af3f6c7ac9121dae58de9f1dcbaa9c73a357f408b870e62b0c7db1a72c4c440f2e6fe90b199b9dab29fc23927190d3f2bf8a7ee926a152e64474283695614ad696c85ea547f5f51d02d1b823e3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5e7c63276f350f04816a6ed9f98507a78314f1d99081fcd906affa3b8395fb58d029ec657af82e77ef45611bc988095bba9c26f25f8fd404432fecd02398e69635f3315a824d6a98b33eaf6a91f12957a5e80cb48d5b086c795eb3b1e04da5432a7e8be3d683addc586a44b6243ffbb7a979bf9664cc7ec41e75f267d58a7127\nA = 18efe267d4c62576294f4ba44c67a058cdc0bb44c48f4035682b2d6b8a63106081af43d99098ce133f8d7f9cd04d4dd7414f704e32871d43d6e5d73fa9f447873168b43b32d6ad19378d74a967f92ec7629a690d29a62a5a6e734e9ccf5b84857a00d97b9db846b057004b03d88b827dde717fc30e6a5246c752d65dd625\nB = -ebaa580d3eef5361547c692e107439c8391ac0a2d1cec0cd275d0be69133eba8a94bd186ff9a129af3f5a015d5ebd30215643554d7064635dc11ec7a8ed2200fd637b099e534237f0495d2b629abd4c8f84aa1d925d53e98490d02f9fe51bdda08b043f67f0903c0195fcb886c04397d3612e4501ab8c7b7db", + "69f781e169\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 76fcb39f94dd2756e8266c025cebe8e801524a757b976e35ed45e3da3db720061cee9037fdb34776c704ad2059ad8920e400bfbf10eca9bb157eca7750cc31fda06473bd22d4def80189c47ba32e2824c721425f225563df2a2ea1edd090e01c0bf980677db5a5dcad37d21a68e2832d1012586f506480e929b2fd9bb4aaddf0\nA = -75f903ed9bb0b6db8e3be16e797258f6c18f6cb7b16f835f04e3045f7e4974d7a86a63f2ec351c88fadc0635b6dc83a797cdcb5cce1a1674f89e44190991e0930575b19e2aa1512bbbf2ef6f8c3e707b17516756fadb635d8c6bf9caddeba14834b5950a4d1e98bca79a4d15e5fa5fa3c1727d7a49b33d481d32fb14ae4164\nB = 4ccc582c8460f7def2d26167b68788a681c41bdf6dc805dca83127a18bff6f5ebea6db75cd959beb859637b200ccb5c7644d571f436e46a357d027edc9769da226278f7ab947963f7caed1e7e70e572980e960e9764a40c6db67bb526694b084976142471270b2331da563a10427cbbb38e76203d7da5d67487eff701d75188\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5adef30c67aefea4da3884b8a1d0ce6724492bc76b477f1053621e7d19f3cac15448e9401d34e05ac4b508b9d1db9a8d323cf43722e0af6e3c3b6d463c6007449c3bc3236d156cdf988dfc308a1b4911554ecace52938a7b10f463d14f917ec3d9fddcf6d33081745009c59b58aa22bcd7dd8c3bbd489997d4e0bff5473ab9d5\nA = -174e8e057a1d66e22eff88de26f43fde1c8efe5611f6ba4f318f027f5a5818df02ec3f014dfedcdfc8c143c5005c3c5098d409710967c93474f5854c1113fe4030e6682bd56d389ca8b9a4587b8b9262d146bc92fcd81d75c3bfa4281898f394f45d5dd11cd4c7344ee7a933ee346bdaeb6f5188967c388b919a0ce6730c0bbdb\nB = -22702bcc4f9d5bc6f803af6af8072780ff7de7a346d6b9293ca751d6ee3a81493fa86738c44cf2b7be4bf14a55a4f8179c35c09dcb1485f4c08ec5e9f9b1efa91f4b5f15a31a46e1ed71cd934ba6bd271bb22bb5703aa468d297f360ecbb48f9fd6c572683e83ebc3d432203347dc62e19fa06f93e087283347950829d4256bf5f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5c2f67b1607776c10fe2c30b112e541c4d8229f5f99f615fa02cf715d3f20556a28eff5c233c58994e9c6c1fcc37b3416b0875b9a62fa5a09a4b8f9e216487203b387ff97fad1f39f674ab19c5e34cb2f162e6b0b0b0084f0618e64928423b73b189c744e3de9fa50d66f45975f68b14866cc16c8c6c722a54420adf027880aa\nA = 67056e93b69e8a7b789f1f8b835d9c6ecb7762f844d656b26df9844a60bfbe0d55684f61debeed31a24ef4246485e8a1d43d49eaf97ed9e7b9f2d2916a8d85b8c9e8ad5575cf5a3fea42392e5d1dfb23f7ad41a7b56a4f21e2828aab38a602d560c99783a4f807120292ceae366b1fbfb4be8e5d4561bc8944e7f17ebbcb0fb6296\nB = 1f874f244ed6cff9f910ba9a58db0dc0a7435e8d99ba6412e976b8f64d4106d3c5c57ba079384fced1c261aaa538e131734451fe84fd3cc5cc8b3ab46b2031f888d95084cd3a35a61092672a9118eee4ed1a0df0409e3613b3ef45a8b16b71ec892755dc3f83c5492b67fb9a143ee6102d053078f4875636b20b536d5cf851768cf73\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7850019c6712f18eab877faa8489daba23cf34b512a3193852508185b13cd5a2e9f503fe8d61b74b5d3930021a5b8c38322aae9b9b1b4814fa4c2c5bc409b58f11fc8fd7854b17baa94a6bff5f234832f9468d90d148fa2bfed774ac03f2dab6a506a70db4ce363f932adcae202f04fdcae968f632dd674416c23d4e21345ef2\nA = 1e378a0f27e6259763890d29e112e3d8d2bdeb9994c49fb67ab680b6e71a52fa0a7db886d3baf52f36d943b5430ae8bcd82e229f4197239c35678eed254c5816722b995e9c311be942f8124e2f80c1e59658433a57f346adfcdb83202e55457308161d2f928b60efc39538a6469f90f1a868cf6077568c8241623896ddc2705cf04e4f\nB = -f4ee37e39d4cadb692bab5483ceaf0258b068f2c0354c540438803780c983469ea28324ce7e209c3bf55b91f0a2f4544bf318585e4514333eafb9b8c2f02170c620e9b5280a828ce1d8dfc64ae9c28577e15071825a85a59656c5b47d9a382af6b78a5b3dab1078dd647e0b473174b8415d401543d30a4018cc3eddbfa546d0fad9cbb2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4c8f8b671443a3af5ef5749885ce5de8e2afeadef9051bc49c0d7e72922d049b1accdb79d82288e472b07578e8b6d2176d6cbdd7f0caab593dc0fd9224a94920235410501fddd6001b62a7f7d8eceaa7a8e4c0de52029fae68656e8120972b5cc1c2e909c2742e836f2fecfa51e12e4f8a2ec7e69eab061c81785374ac607fbe\nA = -5769eae759dd6bf94468eae94189d3396886d4569b0ce264c22d39b623be3abb01bd5008b9fc86701a3373f7764118becadcc69481cbb134c20f669cefeb376dfc489dd4ee91cb333d06afa391dd322abe2b3b715d11ee372666473a473e29dd90fcc97e939049b455be52b3f288db306999019c1177ab5820d94859a9d2f050b7ee1d4a\nB = 44adcaf1e2afbfddae19b23cfc0f0ba1f940d32945d0b541db23f3a0a9d06fb1f67ade9a8e620bd96f4005ced99430c7a55eb7e93a701c829fd5b9e55dbb4d3833afbcaa0d9c946916b1a86af4a6393b1155c6439b8b82260e09ccf0ce5d1c4856f4d524983e4b0fa123267694a1c6118beb8be26113a02721a02d7b0ccb01ec6e9c0f9e19\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 51e25767b8d4d7b2b0c2652d9ca6bfdbfea06acba543b1bc8d3d25b2fe5f2998febe1a6e742abc3f482b4267854c2223a5918a9b5c84e0864278283bcb5bace0c046db1d0240443404fb62d70ebff3ccc655e5f5977958df4c878d9859a69731744f3d33978ac31551487270bb4fb56ccbf59402ef9fee42cbc329420180de08\nA = -1966812979042198f70b3f1238c93ac5c6e5749f1108c2bba869b1dac7680f910e56318c9b59be9212e713a348767ba6e75917fb599e929ea2144880d18d4fbda4f4663c7abb49b02245169f385e09098a4e01b56dadfca8c803acb7cc244f3c98bc17440ab2afce318476b80e1d0b4ed9a8d6f2a0be64633f8faad5eb48de2681a38a633ec\nB = -2e4f5eb92fc34c753c61dcc826abab6fc4f427c6ac7e73ffdf65b1037464b2a9a0b0290e713d81ab57c0e1dc30e76fdf96046fe10a34cc4511398319ee34bcaf73763a9042fcacf59a100c43d3333ffb3743048e8df0dc61fd0da3f935fadf882ffdfa9f0f42980c1af6edfdf161c4b16087e2b14277f655abe54582de79c51193e13169b55e6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 33539b5f38a9943b15801d449adabe02da6e21651d96acd9aa40e866bf65015fa40178399254e8af6bb082d021e2a05da0f45b699d193b70112e114f0d25287476dc0c733c5cf9df57667ad0d3ffc4ea2f85b43cd10459cdca9465b0974e578c00a6e275e0b97ef2a4c9886aab7b5947b78a88f84a3f1d8c5f26bd07bcc59886\nA = 531b891fe9e8db322cec59a2115574c7a304c423e6b11516906b840542b2c608785e2c18033262ab9cf68f63edb40ad4f073ce8841db602cf8fae0a6771d741c6392976c9b333ecfcd0c8e9997da40616ae2a9e0c6be93fdc7af0dc0668ded1e42a9f729c70f74500ee76a91d3d993c075c2f645b35792a20edf17c157459e35c0a48da6c4c6f\nB = 1a6fdbfed1054a0c5758f92f72db7e5737b0740c4d8c3ae4713366ef6709b21eaecb6b74c92541a9a0c99ae18ac6ef7de79d4c84ce39ad59cea9c203734a99bbb895916275e8778cfcf7fbb7b7d081a677769e4ab96bc7bcf23303100e629fa8e07f5b8fc2e39c7b5724c72907eaad09d3088783b3118e57c9c8ad1799b43a13f73864c5602c478a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2eab6018361f557ab06725ad90f6886d4b468ab1a193f8fdcfb4ad15fff781c8681329a27aeb5f03a81d7c404b8017b12fe23165e941ea767c733513a07e921aedf20596763f6f977316e37bed70f6a617e5c2757c229c59b3d7b1fe8755b5f65f7f407f13634aca7c8a267e661ae2f77fc5a95f56cd6c8458119df587478b1b\nA = 1cc779145b2b7bf9ef4c9692845e162329940f96eb43e04db8728bfe736698082aae6b6a1b3c32867c293b08547a0941cf4059d2d567840ab6ea526e3724ad59e715a3782ca656cbb739dfdf0c113a18f0dd62423d4edb60057fcaedbb852178d38f1b5a", + "232842b4fc645cbfd97a8cac0b094b870064302dcdf23df2c9e9f736d93409cbb8ce9ab3\nB = -cbba16086b51bd83d3460e51cf193ebc79b826e4f30978274eac3b2dcb04e9d7b56a1449b7cb128bbfeff5c4720bae45271fcc64085d3ee501f0f21fe73cb7db5f275d88be55c339f9180ea21a8cf3755a875331931b75d23f57c2030c89c6f9c1ead431cb4dbd4480564c83f8470610e5673c7eb6c0fe7351ffd7ee460df5db7872c67041aff0227f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 96fd93535728b961b4167be8b304e570cc34e787c12a9a5d76e099b336ed6b837cfc246c5bceb04b0f4744c5da7071fc01d70e342509473e5bd7c60d6046c9b4f21c5ee71c4e678447f837db3a7694fc3936ca733efdb7d387f0f6e263b3ac0b89054a826da9716691c9d580ad38d701d08ca090b6c59be466e1b9833e75d820\nA = -6791fd686f46c3773fc8d7f4753d178a93f6fa4941f4305d9689c2a305bc67840bbef80ff05c7bc6de3a595f73846609327d28540cd705f5aa94a3ae5915ef55304c37c4c43a4b46906889331ee16585629bb303673d439de9c0236f708fd19a977e6e1032e0576a921853f7dd328979ad1f1aa945905dae93a82b3af9451a541f544c18ed2546b66e\nB = 6ae062b39c77bebc2fef05743e6d35e14a31c6fe1fdc42d8de2db94ce70a6d60d66263c7414b1081ef2fa6ab511b361b8baa9c71ec628dba5bfd772c440baefc2fbed68d40897878232d9715c4b7e7c9bdd41cfe7b6986d825f68be8cc16d04afb0cf593f3028f3dcd91bc94923f3d7211aa5f0f12d3270e8df8bc191808f0e266c4fce2af97ac7ce06b0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 949ea5f645ffe5d0d03359d51a663c7dd6e6013812a47be309575e036503126f48677c68c4ef6e7b3f72d76657fa282ad5881263e649b5297da82e24298300d032af3f5e8309ac7eb597b16e257a6f7af3476a264415aa7783433e83be57ffb3fdb404a9ddc3527d6a9c297f8cb7b6674961b3af837ebb65f218147a46c39cba\nA = -10f59ba073126d92a201529a5374500612bc59a9e66322c6706b422d35a4f82d97e668b268f5527b4641c6099c80bcea504234f3c1e3fd29eba0f161da97c50aea542becba499f29d4ba5571873d4dd9eb3f48cb26fa6c929a704fe8e49791b2ca3293c2428d9cb453263935c9c90a4a2b39d23a0baa12535845f907d42b729033a0a1e74d18da30a88ed\nB = -34fdf9ae6760d4f434d09ce2a7760ca2dda14bc256015809745524dc49d841b07102aefe5a1d0182e3e09d4d45b415e46f653185742b9b8ea6960160752080e5c9577a12182ccf1a293407b534ea8ddd33ad16cd19ba537d8db5b542f86a2a292423d452bf18d82361240a7efa831518184572c5a8b73b108a81d5036b3b530d98bd47c7fb2123418f12e05e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9ab739ddae55a0d71b39974628d4601122ba6c5035c3ad0439691317f23dc33c0014f3e870a105e4dc1432ec79693bac658433b21cfc218ed411e003990b94ebfa87767f3614ec19f5bc30704adcaf85a9d3d15ea764c8f0bbd52ff388659637746d39859398c79016ace8c6f97d3a5616711a235b85f334fb889b9280ccbea1\nA = 76b15a0aa0f59ec804a5e9a627e1fed524320b29120b6789f8e71b1ac4e00a9a8c826919035b84f87d291e2f35460bee181342136dd9eaeb99ed00c6328b8e44c49ede3921d6275f6e7f03de179fb2374ae2fa6c58852fbb2649e214691daef945ead6c8bd5a53ad2b130e9eab6ad046ddd6b80874ca6515322bc171ee32749333669de0d9c883058423579\nB = 1fe2171056ed4585a143b6b2bb5f44047664f64d710dfc05c18be5840ef9426ef05b6e92e4ecb5544ee4622e9030153dd9827f2f01ef38e62b88ecd6c46b4457d16644ef6d863c226acfd6928a40de614a5853137124fe69127a7f05463eaa49bc742d8f7be300d06b302dfb0ba86801119bcdc01b516afa360aa8b22b7c6c1839cff859ca1bf26e3f7e030512d\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5631048ffdb2767aa04d59d8a5750016b38b983a2d53743ba4de5d93bcfc8ec30183a84bb1e290ef9c72c7ad357728acecfc613a6f9b3d712456d545ed54a337930937f4589fe41e66ee930db3dc10a4fe41481008c69eced65b9d1c46b8574c5ac8f7d94025d8fff00ced17a5e17508527681bf94c2dedd51502a2c4652538c\nA = 1aca12b1933f25ea081e12ff4a4f6f9ce379f96d976da2ff7b8eb8ad791fabe31c1148fdec22dfd67828e540c955a1e13f40c5b125e1c7e6bd839bfa84e5bfb58bfed76058c6db77af7a34ffd25fabd60e19f65e1faeeea6371d7785f2e5bddc8650a7492e06691d61f997483661eeff54a30656f1daacf31182486bc40647975151fc05d2f64b50e632f5d5c4\nB = -88ed894287043e7e5cd2eda3c1e5c97f85809f7a246b0c20891fa9a024f3aba4ec1f3d112580fe6ba6b0bdcaa1325ac7ec9508aa88c187af08e4f37631eb6cc97e4481b18f747ce6d35ff355e425a4833834ffb8d34a818bdb015fb818ac9f58feb87020234243aff912da5590ea3f6cba74f1a9fc3ffa2b4aeea25479c55a3b572621e75d86d8c8f6ee4f587e0f5\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6ce341aa4a571cd5bc110dd436acaa09f409661967de0bd096c77c60db58b2b0ec95cda50acd7fa20ea4266b2c579eeb6ac214a75d40abbb70845db74c4d6c93f8c545add269d45fb15d985e7e630d0425565d06dad4a3ff9835411e51fdd9780c24f466dbf29244cd1b8c3445af181d0928db399bbc8632f7ebcb9d48c0b754\nA = -52c53999b02a92d6254557203cb31a21dcb896495d1f29f3277d19129ee43e521ab9d5a297204a844a9537d63b74686eceba72ea2e7b98ee8895513395cf7c44c99348f5c4eb657874a8115f0027d6a416b8a04a1ec0e6809b7701ee7d41e99996e307bee9c295ab3df1faf674e0067d0ab3bec4da998580203e33760870ae472a3045bbd66e352b8f4d284efc00\nB = 4329d110504caeb71ce0453b0706ff675f646e70a6bd9575791a38f672eff226f4958f8b1fe4123c0001d8f8595d8030d0e9798232942725a9b9d654ecf50546adfba7103fed796b455ffbb4c153e70f941bef7953c8a210d6f2f4ddf5d9a79d9938503ae8f24d69d5d7df1c988630ed960e12dd877bb80a1ab0bcf6db67e0c0578fc0c40408f72b19052534da8d31ed\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4b9fc1e0eb4be199427c48bbe1b53948d0135bc1965b8aa5421a4ec704b13cf934c650405ba02ad611b0f29d46d82d4a1fc5a84651a29364524e37be2fc7001cbd3c792aa477802999841ff19620cf66dd2453c9b05aac349b9094d43b40e358f32805d87cea3cfa98e05240ff95ec57d88e0a12917628ebd34946eb1ad6799a\nA = -15a223b691d8b3696306b0ccdb52c1d62c7c2d1ac71e5f07cd8fba960417b42fb5ebed5eb9469be67f231b5254bb0fcfadf5ac5d2906769e8bf8292f0442986cabd88805a162c0c1f60f9ff0bcc2029ce33452d05f754375c0bd147fba745bf8a0008792d4f90d0e0f2cf391f2d7865705544f4a220ded44732321473c0ae7870394d4e625df11bd0923340cb70b995\nB = -340e5ccd644849d982bdd455ddb3b9a23ca14e168bb87256bcc370ffb6b7fe78fd062b3bcc1ad3c8c3b8cb549f2baaf1b7f0f6522aba02fd35b651f7de52b3aa2e0e40352bfd6ed0f84a2bbc3b3a396dc8512ca1db01cc69611925f1037794c82a418f10e0d994f458d1f19051e8bea32b90ce744d46718f42e711c094ad0a1ee96c88920188078f1b044ccf307e4cad7de\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 31c090e5160faff9a136a7a482b42a43ae3c7d00c215cbdad28804be0e7b12b0b3af820c1350b1622a22c8875f24d48ff16231c826d1a946c66f70aef92d4e6582e3ce9213d907267251ac74fa3cca9f1c8fd53fe9898aec19936a2b797fc345d68f0791cc740199be39c05053d5591d874b415e62653b04a3f41e263d00f230\nA = 5419e87e50b28b6d24927934b541d8de548a8f4ec7e9b00aadb6d23f2d33406177d3fc72d29ad2c2e141ab2916adfd30ec4791c626af61d8d192276d632aaf3b54e2ffe83b44f6f1ac441e6823b6b58cc08fd7a0af945a02eabb5aebb2c7ff0622a17b38077cd0cba906ce23e71ac7f4da40ef6066565b4cb3a62ebda28f3629eaa251dbd9979b123a5447ea20331723e\nB = 184782ba4daf429cbd13ac13fe93fe5833f09915cbbc707feca3293e505ce9cf0b4b12ffc8b178e0a4617f809be53d4895a4182e7a8a65043361e654befe8b01429ba4b7420193d1d7d90930ee19cee0316f33a5795335f5fa517e1ffbc99b95101b0f936353afd3bcfec34851ebff1ef02fea991a01b587d28640c935ec91496d1aa3ab8d38a6ac75b3a4198ed27b9019bb3e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa4", + "0894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5eb9f3ca660de481968a3c7321281f22fb9273b16fc10d8eff1fe34842364dabcfaee4993c1c8ddb7c8d6e509a8d2afc005075d5fd3c4471f0622753c7797aea900e785ceef905e2606f64f34e47239c40b74f07e2ca70bd5a18cb0a88780489f3e98232221f65ac9c5ce703a256b7b75eb1dd38778d8bc05a37ac9ad8d36b35\nA = 1c73d8e3d5db127a81477a5c4c6d61ac62af446981773ca15a9a01fd5175a2826a8763f91d68df28ee606e8ffc203305875a238d2095345556f12f3b5e10c5bb6ce3f90342ac74b9ac057195c863c4b9d28ca1d958a98649c7f8897bc6abbc39becae963f61b33bab4fd20d9d0e5464f21c2cdf06d00f597dfde45dc5919f5124f26888b12d72cbd2f57de3f2de7c014f891\nB = -e406fb60e35f0abdd313b8431f4cc89fbb034daf71fae0cc727e9a93cdfde53566fc74e48f4cc2111fad158c63293bca0b21b98416381b81d2443d0e91647679481cd6b6869b37112d3b6e575eea7fbb5bdea422558d817b49ac36a829926553202cf9dcef09423c085d26176a89be741ae20a434ea461def090dbffaf2e2ef97bbd4ec779041ed69ec07d125c7b85a2d215bb0f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = acf9d363fc9b76ecf7e61c33270031340e66595e559dd1c9dd4d2243819b660183521a4124558fd4b216dcf5c52c4127fe517c48cef428b9ee0f1bebabab487c968a80b9815e82c12e807c096974ea3893a8d5597f745365c352a6bc6ce92479176092f02907538c5e784bf26dcde7672338f402753b08de8aa21b9480df6955\nA = -7c03ba6e3939ebbeabd35cca277eecaec31f326ab75f1a29e05af50c4e62e0175d4d6a57acab87cf1fa3a51791e9a2b2d4d5db570ec3941263902b0c74544c323c106557cd5139d2a25f3c3ef81ca009d4e3c16f1abf6e2b5196df1b30def46d61eccdcb3741a6dfc8e8c5e6db68ec29c82b0adf6e35ce7aacef8da806b3b58bfa489d319869b20768f8eebb604a9624d048f9\nB = 4e021959da96ebeaad17f9896ed53010d80ed3fd4c3a826a266e82b80ad81b3032303e7c0e58034a652b8aac00c08d42a530039de60d74ad349438f5ecca1256342ded6f30e3bd2aad5bf2b49124cb27f45f697e157550dbbb37f5aef0f04839aaf1ba43bf1e77a1529818d0fa91d940904eda6b748e5c86cd1b37592542c43b7b4afe2b8926fef6dc01784fa431d43900edef27f8b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 24124c69aaabec7a7b4e7a82245f6cb14b199852a8b314a7b8d9049cb66096d5ac93ac75eb58a2004de8b0fc8375638c0878fb6a45be8bfbcc292e3571df1bb8d6e346d5595fa395fef983a365e4e868154fb3e337d47771419e7f1dd5e4220900c564d7cbe8e7792ab288f99d265aeb296c5ebfdaf08b88d9b30ac660cc3ff8\nA = -167c959417e9566c93e7e05d2a410f4850e3a313e516ec958c3d2fbdecbf58072d05691c68981e176a867d7467091dfeca11f695f750c8c44ebc4d08e39e679d96c4791ceb1ea3b89fa3ce26f7ef214c5368c03ba694f7ae592bcd8ae53a66cb3eb1e0cd3c105faae6eb7e7a8fbc88248be722406f2d35e46c751b5ceabd992091eeba15191ccf6dd61a7ee0c624d43b188c42b6a\nB = -343940f3b2a5f73a51d6f609e8af306f44ce7b5c2e79edf6f4dfc07866dc5c4b2e0ba48099b5503af87762a44ae451d166f8914ba25b3cc41a766583bf73d27e40784064582fd9fe952fc00e9aa2d4e4f1ef35818978e725e69c1bcf267fda4d635d1d292d54d3ad10bae9763dc5d7f7226f371184465695f2d384d749fe07967a1bb64df22f294ed88b13600c7068d881f713cb8e3ce6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 50cac148215963e58cf6d2ebc36fa518c63a0ab8fb136ab84c9657fee459043ee9f42aafec89e8ba5fd1cc5c4495a41e80590ce197e12c087ff7e6ea88ed798735f55a1634562b82f8514488ada526e5dc10700058980885000e266cad55948d1e080f6343f84b12a3698d9ad5427fad4017d931df77ed2e45e2fb8380b7fa39\nA = 6a9833d768a22ea46aab1a1619f30283a1ec254a2de5652981d73146aabe31041ed04d271c6f2e5e2d090cd615518a06563a94ee2b12cf9f142de3f15599998a712974d0ce9b122a2aa65bf8750f54c6324f12e321a888154330f0f9e1e5b7999acd70d4e6da95c2df1da2d19544b7abd2bd3041e3228c7cdba44f7d1cbfbcf968f8fe87fab523eede0485efaf5cc9e56095cec8983\nB = 11e782e2b3f469b1e3d14ccd1b8301ffcde7e371f6e9afc99af5809110c6d70e1cca5c0bbfeb95fc3ef8352581c11ba75c0f8c445ce2aea903769a24289581c95ae5ebd9553fee61a30d155bf6011278807833eb2ce7ee2a98fececa23fabaaa259409e88e3c4f4eb1e04176d44878ad3f6961e0615ade2fe86b6eb02adeaa7c9019d63231a28f84b7dcc8bb0e71e2a717db09301e1dca20f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7cd49d72bcf5ff4fa2c686f21e1f0146c4f24b9ad2e900dca1c0a5d2fac5047509064e65ac582946b251a3f04850c9abd8b80c92af0fb11ac13debdae8b94927f1de0e4bb217e78f5d04897c6a0762667d3d883cb754dc610442c9dbd44228a7ae4f14fca145550d813655befe3bfeb52f1c76f989ea8a1dd9c10fbc7e9d6574\nA = 109fe33568598972063279b71ba0efdc2e03f770cdec331428fb8ca084c9b20d0fdb5cf9ad7ce90c8cb8f0fef10d219d7dfcc6b4599440db8cff9971da7852880bf004266886eced8763b3569720df3a1fb0dde2717ce0183f2250034871146628430f206c12f5fd87574c206b203d90c0f2c705cad3484c73da8bf4e9f7e1bd433a6f7fd27df63079d30c490aed7161bc594eefad4bc0\nB = -b95da952cabdebe0194b7fba519768e1b56149353cd12023b97397b59e0d7f4dd1d27b65b833948f58e66d3f6928cc3140cced835dbd612cc82a7e9fae1621986f71ddb6707ad57926b03e87e165d30fb145795a70627975bbf9d9ac9bce07492de5227c666663cc28b3e70b19dbaba7f16849535ce5fd61e91cd2875e0a534a10c60d21f919d566a3469d108a35ec3f023210efd5d318c7210\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 98a89cb3c9602fe503c32c44609bd4487b6c8323737b3376dafacc3eff96efcce7a31f1b61ee6799dc9561e77ac058fe5195cc013e72a2864f7e492d9f35244b321d46270a582f6f14f15fa8203d392e81b183a1d64d48b51d70e38d49c93869ffb9d7509f15ccde547d2d9c4dccd50eba49190b6e831a9f4f9000a95dc83f3c\nA = -67d7fc8f1766c40bd476cdb65d4dd161c3d4c2c5860a0c559f0e87ada213c9ed33308c36bb1c7d615fa69ec53656bbae6b57181a0134af23ea2a75f8fed3290a2f483392a3745fb57adf2121738c84f6d34325121a702c8ccac0090ea27fe9a5ebb6ba9d4f397e4a7e3151850b3d7d25643398bd3e4c1da081471389799245d986cab825a2e6ca72b38ff978a2753c835299ab4597bc65fc\nB = 676ddc4d18960817ff8fd2adffaa68c87d234d62d445d6ba3847ded849356d929d9e4ff01f517d7b1c0778bf90f475923517d855956f17ece1e032e2fd474d2133d6b8a591995454d8b587cb4f6fdd0fa29305f146d340cbe6b6efd28a926c73735621be0c5decb792083b3f063a43dd9f635e03f78c1bb56389a5cc993c8f36134d755a324d4fccc2ac3bafa270df67db0a4ee6ea4497aa33b5a8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 76c31404854006a7d55554762094df6e11e0393f5b0451d85de2e5b104432df72023a35f44da10dbde01cebf77b8f9d3ad582373c5d32232564729af0d03c5450e439045d96a2f0a38871c922af2bd38c545d219adce0ec80fccd121d6a733bac09253604a8a0b1ecf0f24e44b818ab9e9974181cef10e9eb17684c57d72257c\nA = -134e8784878a8f3cf49ccb952075f9f9bcd24a20f8883955f262867045c11a9c566abee00638927e5de924872fb98f6376e321ebf3f567db6cfeede62e04f839617d78b7c9d3487b60a0d3897b3fa49b14c12511d04854bde4a9dbe5f31424a3d05cb75d23b46f6c0819536020880afa5a2c173f6881754b56f82a2864c99c820156f96b5cc4665d603597331d98d90a52f4a30c6215ee5eaa2\nB = -3c5c0d35de5fb21c84d2db228829f43b31132b582556b92b495f59df502a6d00584bb5bacd9b8c1a8c7eab91db0ea24b40f07e62a712842d5c2e1d208a6412a068cd5c6394d715260b67fbc03e3ae7eb4862f74f4d7484f747774fff03830c65fe022d579adb6737f6dfe297db750e6a58d1004e7e2716838befc2ea97179ecd53b7f36e3540e1c3a0f3e044bfe2d0efa9b89d2d308cbd0bd88ab3706\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5b704b3181e5d049", + "4937b4d6aa8172eea82919fd1d884493197a6a85ff047a7bcd5dcf072bdcef0287be20d4ac49918d1df550d184f86d7220f0a84fc4da3ad05e131c443fb529df01fec9fe4fa6fa2f36e791f9e16b4092759016d2f9b1ae7c3d071c57edf26386aaead767a3109c12a5004c7b9fa595e6d592daaa2dd1df04\nA = 48a0ccd2d14e14e2aa862d306501efe5de239e8ef36ff6251c861a0aee9f739411f402491bd99aebacdc26c4f30306f9137ffe4579c2f13efa81b979ddfffcd23675ac6307c0aa3ba8ee77a2e3a3c8e241bd2ade6484e6ead32ce8d752fb3584d14688f223758c5cb8705cea9c56136b219d87f9904bb56be2ea1c9a035df33455206e6b7972cba32ca4c3db41991117d88da3521780fe65c4023\nB = 160120a35ae3edac3edbede9ff1c6f317d95481227d87785b7ee46cfb80fac9973e418244884caca3211a3f6cd3bb419cf70fbc22d82ba5ab98ad80e1f6c2cda753aaf7be78613ef25577107a47ad1ee3c3645db85c4d29bd77900e99e1f439cb23c6c68662c05322f94feffcd9e37d8665cde984387093a043447de590e7874e6acfa37ed302040df4d5c3dcdf9fed91b3d17ab5c141d4494d0f301b508\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 448c3a64958b82ccaaed3c74706ce0a48c5e059c3610cc03a6b5a03a7de5d4f1d1e4b08a31478fa8edd58401f0171697f0662146ce2b371e335d695f9e4a671255f29fc0b9b7d1b2eca4cc7f8357aa0920b5942e31bcfae84e909828fbe5d02251ddf10dbe4c15351f675e96e2eae6d044da1f0858ce8ba9b7aa146850b85d93\nA = 1b2a52aefe44170376df29d17ae2dc1501c9c296f72f271c21f53db71247e72c3eb2b780190c45343bcc8f548507559ced3bd4a6fb13f9174dbddf965b9c4a56c3d88727736d78be9db2268cd02382e50c6fa28ddaf8eab9f44ad45d5882a5100b3027c150a7f3bb36f29d24a76e40f3820ba116d645800459f06c20679321cf5be72450879462f0eac99ab6ff8d26b464cd0e6d78621c9263394c15\nB = -b7d9bd08d7d8e0e9596851b7e03c78973a502afcc7b5fe5b0db6034ebb8a11df1ef7ed0ae1371eb4111cefd61c61935d768be3e3755e481daced219874cdf0d07a76e7144be626cf1fc21c8a0e9db4389ee213193775e95d4d86741d8d8fc820c239b7a90937000dc3e89b2fcd61b44e1c38c655bb3d31aa7e422b4406c9e4a88e6a2c18ec7c048f4a6b5b270c90d9fb378f64be3b5b351621db48a6c18625\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2192157490ae044a26c23eea6da51d3a3dd08c7fb67a9beb76d37ee24ac0089863aa7f00849b81bab8259f3a0e1bc744d841e07aa413c286e4bef2ff3356bdbecee756026915894584b4fcef7e49da4012cd9fcb5dbe3f3b867cb6a7ee959a328b0fd56a9eac1f4e40a22bf0a30073cd2d48f99245ac03c373810c54eaf3306c\nA = -598eef47b40d1fa1ce260edc561bd1c1ab286a7e068af412ec2baaecd07c5b9cd596505ea1bf0370ea961c4ceeb9be76baec74e6952cb846f20e5da406bd01368b85d59569b403b7a305cd7448f331f10a34def43c738fd633df9a3eb194c32d53aeb567889927271d71d3929d43fb9338248b64f7d23cd1b053239e09cc2ccf5fe9c9ce240f1a10fb151a8583e4b4cbc70ec3082dd20a9962d564544e\nB = 559fc917de34bd7dd7a23a432142ed79e3ac4a6caa357eea21e423eb9af7fd94f1eca735d2588ec4c2ff013520c3a0e209627217cc69bd5a07ca46a43ec1f1bdbee5f09ceb1b2c18bd388d3852e51070943f16152a73da624be680c671057677356c6f281a4ba1f7c60609125d7fd9086c907ca5c191820d80e483886b70c1074e2963c49996ee92577334881edafd88270bb967da795aa4fefb739e4367390ae\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3488bf00f67b852592922fbae64fa56d2e4e7081678e789bbb3b4f48df62576d537da2e99c9bdd721c725b9a828194662bbd51ee20ba73d4ed5562482540880686d9fb1e8ae62d08e39fdbbab1d18e399ebf07b3a6559dda8b043fc25a8152858d39b10ff64776e00a839950e7a9ed5ea95b594b6e9e9d4348ceae08071ec5d9\nA = -1b135d8cec9969561be396323e2f8be0c60903ca59b6c418cb19876e9e3cdcb9ce4f5251eadea11fd6e785476c70822aebdc94617063d161ebe55584a8a774ab230b8228a2b65bd5a6c873bb6b261429eefdc7d0c64c7e78133e739efe57f835ad03ef8f84601e1a2310659db5e0ee706f23e3c5c38c9f8c36e5b15b654d1cc528f1dd392f1b08921af8be6fe4e4e6db774392441883ef867bc729338943b\nB = -34fb63435c90018e5843098e379c76ef3ba0615b6b500854b3dda3e77fc5646228fcf3a6e1cd87a506e4959ab05e24474990ad98ad0865942737734c03dc289307f1b1f424b9a8c2264350943449b3d2b0f71f989039131e23095d122ae98c0089a184dc530669e804140134e5b602861a5e61c030fc3d3b3eef0a59f8c0579fc9b0afceaf16698de3fa07c43231312254c04ab11ad7a29efc4597780c2cd1b64b43\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8ea5fcf7fd41803606c95729d2d910941e43b222f9b0c93a1a803b197fababbd653a92ee34e805906fde29b307a962a294aa4dabebf0d181c046653ad0fe6da1295eef817f3289dcc6579cee8869198c39a9f79992cf6894162d35d812df327a64470c935994aca4985d0e6a783b853ad762338dabd575ca71034e29d768d014\nA = 6858d029a62b0f75e4c59f3ec067e3990b2304c90a097daccaf554abec49a9d297ca14648471dba08f22ebbf8e238c89ea06f188203599aba56611eb3d4df09ea795a7e28f91f4a9a582c6b949c6ffc584a076de653446aff9b24e87202037974aede37aa9a121b5b70a3e9b5ca376c9056c2c91f5d5484baebb64cccb6a09b4f40529afad1ed64b4cc4aca586892693fb5f92edb6b4d5f678f7a2441e51410\nB = 197d6deff7adc30b025e7e418cca0a641e1a1b35f78fb56b9d8847f0690313475e6fbc6f73c3a718b10bf37434dd9fb1eca33a99bbba674195b20d35e3b34ba9d7c8438eede24ebb48e6d39eecd93fcd7dac44235ad32f208919f57b261da70ca378f9b03ae5e5a733f97f0b3f4102d971272015bf50b6f3e50c7b36cdaa14a8a580366c9cb0118ceec6e627827b0b8f614656292675ddb66e1c55355d5a1d78e69ed31\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a25db977e7a8fa4578fc530995335411432ced67e131fee2cd7ff56970df64a6f0f4a7d225d2f4ccec8e98273ec9a0f1aef01dc0b866e425d64e09cafb9ebe3f80bc0ad71c769f1ecd5efdb4a990ebd3a94303f52f4a97e3a1d615918f8b2df5321c4aa9339b4453d7a710a803106dd0ab49c6cd9aea431f97fea9fcae0bbd90\nA = 13f97ba15ce46ae32147a0aa4c1639b6b555f4d8a1af15ede4f1103f7a0b06b4625bf456d667720adca0c4e26e858f008b012fae63cd89322b33fe51e87714519e7dc3cceea27d968b46ebc04024d063b17901a7ae978591ca6ca41afffd81769f04b714134cfaa6700cf23bfda6ce67313988bba5fd3782bc62f76cf551d140c978dc002a779ae37400d34cbea013a5d1338b203ff267861edd88ab8ee1e4c4d8\nB = -88d8a4c8c680fb01f493f73753c70ee753951d4734627da14962e36449db5490b8c575729fafbd203a125b500b96364e6799d9cfcf0efb4ec877e86865eea5e99e2fe5e7655c1ee0eac641e73b71c66d7a72c2934d1ccfefcf59781035b2c7b89e5de3f7d1e9128cac57947d22e7577832ba374492a2f53be37e17733d8bc625fa77fa5cf093975049a5c477f792fe75e85da26cceec820c8b255df0292824b4c3a8ed455\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c1f2165a402fe9becea284dae60453965ce327f540bb8969562485fd1bb60372b8689d9c9c97c91bcfd699dc370117ea8b704f06cae3d972dc6e5eaac971597c69d4dc24a68b256f97229e643706aa6d2d844078a5fee2d08270820055ea58155d7bc754f09d0c6f804e55ebe53e3ec418747d4130cec68533f6f0c2f8fd2409\nA = -626a1580e52ba52a877cdcd62b34cbc7f949148671d4a61201e03e98985d704b2975b9a2d9c4557deae065becd662ce8448171ac582894bfa2c59d4ed20c6d0471fcad1d0fed1291df5e4556aba72f3645486580c8bfd0e3c8f6cb34fe17ccdd75fad4d4a2db4e00bb8c2a23ed17a31e95631320590f40416c153efdaf897e3b278a1faf1917554d9292f90c4edd5992748b58492289eecde1af34976ea8ff507fb9\nB = 44c336d7739118340048939d6c198f73f90e13030b69be286ef920902391d87a58df3632091d0ef25340eab395203e8dcf3389e95debb7432165147e145735d2e3226637b4b8cb7d85d68308be07f217f57fe439b31fddf3fd469869a20f1f852e1645b0d4903432ecd1fb6397db4c11f6b6b9c0fd25778b0ff00bab9ff576b16538a6b7da40f01fa7b987af8ead41ecb66b8940c0e8a1208d0026773e711153d99348e92303\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed", + "81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 98eaf476f11168bb63fddf7dbf3347e619f9b580ea6804ab893214e94ebc089cb652e307f1f37ea7ab9052a352e260ff7d1e8c17461bae68c52a8a8f1a57a84c79b2c8fcc2d504ac4f553d2534f2a776ca129ec1942d83c8ae24c772f6a8429bd61949ca1aa714cc3881ed731497b84415c88ad4b9be34197a549737edcfeac8\nA = -15897a5a986641fc2cda42d185d72aa1552eb92f788bb71cc74c0e424bd038e02c620d0686ff88ebdf0bc1632093c0d89e724e7d5b526b0ddc4c7e145aa90b36be0d8574901fdf286df84a6b52674a78cf21ae4865618b4347bd905461d878537b33cc41710ddb290964c48e44d4d2ce2ed82847de75938d23ed418bb9ff1caa03b5c1ac5d65692dd1defbc6013b3270c4314a45dc67883762fda5509b915e8277c1924\nB = -3a7141f54a0bcef68cbc3006166f7e15a5c2394892a428fa417a485981316a537cb3ec757d4a2473fdec2cd61010a9ff865852af8f43afc79a97d394bb6c58643858e2b4dc5cb958c33781b5c35aced7882e8b8d7b4e4249c2b82150adfb0c8f2bbb1cff3d2ea27ed24eae030ef468ae4d6b7462f0b072cd2a2f02426b3290b87b14d14b34e91a94c5bd69e9eda53335cdfa7df90a57f97f3d023ff85537fe0a8bc5d8fd7901722\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 34464b7a50713d17b01b5940b5acfaa7006aa6b9b083bc17e0535b08783761391eaca8703af2edbe13dd0fe9036d38aecfd9faae08c0861042ea1a25b41fa8a15b7721909783de3aca127e955e177987518dd010306a795bb66466fccd55bd9e2bde17470cbd36b1e8f8b63805229754387a5fb40f3ee9a8afb2e51e25c8bea\nA = 701ae8c5bafab7f41c999e492f04a7626b2b1054e6dce1b83002b2d3de46717225b018733b0fa8fe3f973202da8a090ae3fd14f48b27097513ecd4ceb1b9729e7783c17fee9be5221fce4ed3860275b3b36b7416594d2b65e198ff564e82301cae23756c878494e57b5ea8fd22ad800a582cae32fbc985d122cbc6e0eac77c1000d3ede45ae7aa087534adfdea8e9f924efa1b19c43dfd3b7bc83d7c40df7c6578a320a19\nB = 18e0256543619a750384d30b6a7afbbcbdcd9a2ce644dbfc97a8ff699e118032558f706502c9b956695cb25a46d7526596b3d0b67b69611009265838bec533a9488d24583e7d7f2284e23c3cc4ccc5920fc57e24f60da0d479d41f5b9c6ad9152903a4f37842176c6257fb1e3e0681d6d583e704c1d1b24cf616fe638106638fe9d79a0c74f0df67cb2df9d99185324ebb037d01ba0066ba947d5345cd3201b19769d438c43292f572\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bc57cbb3e1051d3a3035f77c2e375c7e3221dd472edb1a5ccaa7521849fc0ccc7568238aea9335a733d839e89ace6f2b66ef238267e0050c065c3d9553cf50cc5cd93d34fb43c3ea1c31b8ebf0b751f595a7e5e3e860b366229de4286b9d3f0267f78c6888ab3f208c55d9292079116ea0eb9f4ec2934c97149aa132c03336ea\nA = 1ffb0aac11f6d1d257ef7aa997a030e2a12b0615fb11ff04f344f6ecd550e8e77e9883c246e009af33a51204e4066ed4249950e022a61337848dae17c88317e15ade5b5499c0d7597a69a02b6c18db0f975c19c16d2167c583571e947676ae9c15be60e69d76e78329aed5fa57dc5e616795b5487f3d52bfe74b54bbf93ceda093c2e14104a6d2f017f0d200a9fc89deaa283e04b0bd9015ec67598425312868eeefeae9c996\nB = -9de2d82e25b449b8ca4b02b2d2fc0a023fc5804ea553aa84674a815bd74193a2e549070e2cfa0b90a53070646875282fdf855940905f834f5a07f073093c658cd1813fc5cd7092af592092d789ab5481bfb14b6683139646cff8eb1c5dcdb6a33113d1c97d4b587f15f972c06046730b7e712a8e3dd5f4bfd07cfae289047de31776f222d11510ab6b70a200ceeb6802d6c33f913c509b31b96e2b8dba9e25b0d2250c3b102d814683f1\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9f7f4e010370ec1d76fa83f73c80825c3b71521855fca5db06d7ed830c910d0430375bf319671f6a83bf6b57d9d53cfaaed5bc5d615c5690df0067b18791c33cb9f0ac9fa5f0473e4f4eb7840b0b660962097606b3de5744089ffb37d9c0df1123a91a5896d4deeab8aebec469b099a3a9a4f6d822030ec2fc4d11636706fd0d\nA = -7f56093243ec2399548ed95df79363e6ff09de211dfffc314b7cee526535def0f9a8eb9aa6f1736528ee7aae8be55c06645708d576111766ea33e0564c12103edd61ede3128a7a642f968eefd0d7f3768b1325c2dd910d459b15e54145a234225fd29932234e59d3ff5099ec4d5b5c6075f56382ade1101115c7b94e1e2a7bf075dec210fdaf2357c735416dd5d616335002d1cde6056bf7c478f810b78c661a3dbe6e54084bc9\nB = 4df1a6296428d06f51f31a1b0f66d0b77a04db3bb8e1b80d64da649899a1a55d4041bf0bb47d3e3936ee0f3740e1e8c2b235e1b8944d28c7d617d1f968abcde9dce10d6e3c27b2e3607d8df815f5a39da9b5569e95eee1fe5532c0a80011e7415800d8a9ec175fb1d13dad959becf04964b70dabde6d37072dc9f6d914309b850cda33a565515dd6c0181fc48bc7033b314ae0bd5872480e02ffc08dac4e3030d83b33488cf149e19b0021b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6da5fcea305cc6eb47fb17190889e6a39c339da1bea2d7c95e997fc538b4aeec8b0edf7c109faad7fb6c656420f4afa104ada7a0d3d14d3ef0fc6774b59aa2687c0b4efe7c3fc83194a89c832f7168346cadc2b1fa6fa9a23a67c91ad731b4cfb9943738c7f9951945b2eabb3743473d9c0444ade756291f53fc7641501597a2\nA = -19dfb98f9f7d20fd331ea749d2019d8367935fb75ecde45d6dabc815ab9e593e51178a72816f85aa678304e6ff3a2c24079a59aca253d76c4ac633fea1070753ce770765bce47428f8f5ae40c26a3ac91ddb551b3d575bad9a3b6fc7954acc93aad2131b78fd212fb0db7cca4195b41651a5311bbd4d8c64f1c93e6520eef8e6308e98caa1cd0d3c9b4041182cbfa131c4948257f1200b1c5351bee77ac8bc8e44680ce64ed0648f3\nB = -2736d5038c60553927f389c0650bb1355b0ce745a7dc5f52c9909039465344af910a5f6a9cc4ec130b9877c1cbb52fc08b20d672e42b853d26a02bc07eabb9e3f91399db8465b6a8b1c9f4a4b9eeeec6e9b6180f1a770c139c8f29ceced61cc7ba182884ae01d14dd85bc924391333e8ef039b586b6a0ae18db3570aa560c2b0226d5e23e7e753873637c25aeb19e74997da4f5d0755571785bebbc7dade57446e0df4cdb8df23c1003533f60a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c0265805aa8ab52da5aec06ef7cad2026fa0b18edb27b4903e3c068ca6464465e34d3f3bdb4bcc10a19441040deaf5569645f7e09b36c56631b3a6144d6206d39c9bcac53b54210db6d484cd6a2780bc68c07272de03a9bba7e51c9d86cc8883cd2e1864a2ed711d505930143c883c57545e9c40851c6df8b3314a8c9a0d201c\nA = 5622f906b077d243521325be82a43fce321412bdab1f15e4ff0c11a7066a288b7939afc01d30243c8a4150e74286611ac1ca4daf457aa23508a7af869d2d55f54f2746afaec477cd7df0d5711dd636802ae7f673b3f730236ac3899330f89cb71d48c2838322fe856d9d8b4053d9c1e66acdb5e43614ecff954dbe37c5269d7ffe00b34e682c0be3d7cf653ef212daa3d55dff92b329126636e440b0bab55f4810a2849f77c39ebb93e\nB = 1ebe0d1800b1fcfb67d7d54568e45dc604450c1dbe103ee21d48dda300c1d9b9415dcd9f5a56cf12c2ede3c862e895efb83621435377387b29b882b2acac78386895c7daa90810092bd3062a3a4867f92d54622d7f0b89b40fabc4709fd507d4002ca80de231596630c234fa418611ede0ae4a9616d570232c1b03329bad02220ef64e455c164aadc16190ce35b78060a6b117b4b0641fa64dd8e8cddb5914e7657573804e63dc7b216b1a9aa175c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 606d2b6f756548568013bdaba6e811dbae88fb01f5f36d30d15dc1e099d86bdca9fc1eb3a785034ea14cb7f4776586327d57ca5a52ea1b30f26e2a76140bbb0e930c7780673770fe22c5ed443c349510e1494ebe402f2621b1e6bde39b8691edbe5c7242efaa6634553e6af146dd40666edf4a3db5d1e7f9347fa1189c1e5168\nA = 14ea5e6fd612945c71fdb17ec44d95015773edc908a85a6645a8eb823d11226545d05b81791401cefc81ce9765eacea7a619cb482f29d38988d355ce731bc9009969b7487a3acca2d2065c1faadc5d6dd8ca1dcd3f3d4ff61d0a75ef75272e62193618f6b802f70795041de26d6ce367ba996dfb91167cb1fa16c8977f982e1718de7d60275a7f66e4ad72ee55ea06267cc4e8b08f488579825cc674b0bdfd34a01bed08b62004fda15b7c\nB = -8a542280f6c8bf4d9fbc96d5bfa6ee0d16a09dffdcbfeaa2dfa1097a760dec7bc540a0b5b2020bab1eaa594117a40a9bb99c3f16fc340c262b29909608740b8e77fe4706a88dc0fc3bcd47998e88fa02f617062393978ac1bfe14235d43f3d5edbdfb9f140412f4fc2dfc05a700f47b1f0f90da7ae07ae781d9ccdbb951f1", + "9a8b8a9a7dd8a65942842cf207f3baed3a0b2f08a06ad0d9ab7ad0110346293d51ec53ff8165b925c0e7906be8b7303252\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 512220042f151479a6a8b7c743ba83366cb7733caf37164e9c823422ccbf78b0b83f426a7230f559d50bb0ed3d9486c6a6e25f4cf96c4fdcb2c861566c6a73215b6d08995a14569710cf9e54abded1d77fc7722d06fda4557a3a99862e5ce963e1be25336fb42a4629391cde3aacd47ea5f5426e7185c5df27d9136a6df26f54\nA = -4d108217b778694931088bc255d1f69cf8f5a14252156163f948ae58d58f2ed54f518177d668e795474952c930052c1bcfcae11bcd15af168ec2e881e6ddc8de257d0cff90ff3ad409bb3a080d30fdfda99078cc3ad8302a4bdd77de66ac082b40fddb3cb36c75a86bacaf60984a74a0fd575d751ed2830650d85844aba9e3f781b2dc6b515bdb8d9459b083e1aa653ef177de76282e86c99e97dae9c0b050c9e6456a051e7d99adad7be4e4\nB = 7b9079504c635655a588ac360955fceb10cdea5f3de548ca2db681da38c17a70df5798f72cf18691d14a5f400ac69fbb47e64115cf071466c54bc7077a228249209542683ba57791352ef3409f6a947865d8f234ea9d39491b5c001685487b32130bce9aeade97d9537afe3f2f87e8f3315619ef7f215a73cb724f1adca99b90912aeecdc81485c0d00a74387ea99c965118fc6a9af1163e60d1ee6a1eeb12d7c2bb9a54f747a415beb5873d616fa0eafa\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = e36899d83a143c82e19e11494ba18478c0a9497fc89fd83df38adcb6b33918645a416626409a156899c6583ab9a4426438d9c32cac54b78df579cb7b6b1feb3f39ca4a6183743a4b823082896a89f9f1722be842cb2d2ceb605f84a9f9b61cdc7e184593fc2f9ff2994fe6cc4860d255809d04ab47e154eaec9ecc807ceb298\nA = -1422272d9e91a14b38b3e81cbd9411a0cafca23addf4f33c94a1bca70603db879dd8a9c0b95f5986bcb447731219c4f9b32a1e3253b027b7963ce40279dbf4008e526adc0bd7bcb2b533392a105c6e8e1bddfdd2bde7dfa0d2e3b1c6ffa07fea07ecdb9fc828283e93b0ce4861945562478b1a56de32251b7d31f9a2309488f7cbdcc38cd6b1c951570675ef0d61e1df69fed78979dc755f160d93ab5a3e65dc2944d3333cb85aaf87a153a90fa\nB = -2424fc1e71286ce3be684a10dd885e4891b52e9009c3021d90ebcaf68b6db81130bdbb74869cbf142e0f44ae72684fc12c85abb5157987428c7812889beecfd7bb43fcac2eb6298ebf1dbcd2e70e4274841c2703b8685df18f6e5bbaa1422004797defc6ba843e77f891bbb46699a863bc1d77c5e3cab809c247e2975e8170da00fd9c8b232abc3fc6b16951ac4e6c96f9503c1ff2d6832ff9c35b2c8aa408645849c577d2b8599ef520da57fe2a9eccfcba6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4e8a59476d47ee2cd0217bae2981cf25a2c38e5f5d5c30c2d8bf95856a6e8f42429e565f1836365e550d85207246514624e7ed932d6f5802a50ff9f15d500dd84b27729c1717a3df0f2d6dfd40f0094208445193ba6500ba03fa3f4bdeaf9251aace8729b32ec3215bcfa170575e26265fe523cf44a071470e3b1547901e9227\nA = 452cfc78cb9597e67aacd4ec83e5b473ab8b7a1dcb6097fab37e25d5a6e25c69c73a6c20de0e2a744375bbfe7f612036e69c7a503255d9e17c6ec1dc6cc6f634d4c79bed4764496e5c7c026fdf9408242d3b234195e67a5681e7d7b861f58eb631ddb9aeeb0e5b3ff7a7657a7fde5975b8a9e1f643893bac47debf7918c7ef8f6d7439320dccaf63b80ec9761559078baa8e35d98fb9dc242ba83536eef7ba9901395ef02b19990d8312203df7dc1\nB = 1dc222e7a737e6d97a703fa232defc6c0a4fb2bafd247c8e547b9c474421cacb7692ec98f94be19a5e40269e1f5713d06a6d081a943dbc667bc867e481b99c55e437061cd44c4482649faf870d9347e0252ba9dbe116fb4992dc2c2a0583c1351e9e01e71e9324f5fa942322485bca93c2d95cf304028e68224fed446966073ec7326c93ae326a7a533a36e053437910418bf1761abd9c4c5ab7e6f538e9bf963903e6c80f21a0a38a683e8166e4626a8d8b743f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a4d5e9fb7f0d75ce41ffecacd2ee1e4d15f82dfd4decf5ab1bee75fb97792d0d574fee60a30b15af80bd38e6a25b1821e61628dbe456e39fea3f8a9ee6ef3d2332412be1500fada0c1728a1457656eb3e9d94c64fb2d0ac89f10f2b9ff57d73207274ae7e8c7538936cb7241615b830cc9011d4363ef88f51c7b3ed503c25179\nA = 13eeef030b3110451fcb1a258434aeb51d3dc805b38c72ef7c79d4b0e18d600e5dd28b552b59f3dda1898367ec7da5dc6d9089a585cf52002eaf8f9ec64b8d3ec50d0bef7dc3faf203c48583ec89757cfeaf888ec4a91470a6b8ec9f26a6b07f3311b4fe972cac2f2ffe47f5c11d2dca87c62680e2229120cba4de9cfce9f7f5c33af8398c07ffabac1675de1845e05a32536329647214e54e5d9216fc0cbf2730898eae19e425688bf184d16bd1d655\nB = -ea324da99252edb03f40100e528d9a5080c43be97fe4b7e03d9563ba48040d328e57d0defd4b7ffa9bef3ca0d2682aefd2a0ffca8566e755b11f2e3c6c1b707f1b9465592aba6181e583babd5c70588e7123361a8ae77d8c398e33f894ee288babea1d7eb63e2f3de469e502b5048417043c5a9a9a3eb921cea1533162e3ce9c79e6caf62bbe7e17b180b72c59b9ef5fe1a001b733d909a8278029fb4a63077ef9b3545f1159ad73dd75030aad599ea4884677e01f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2f096fb8fe2156c41ab695956f13f0fd9a084f87ea5f5b1acb6b60c62617b8d7079f4b072223ba18cde474af3942599fe070ddb0ac1a99f42b9506a2648e1b8f6106015aba0bf7a824842403bd3f4ac8b6fc4a9861bf0e8ac59be0322f0495e4b515fd579dfef273160ddf96e453f4ab663e703609c709fb1f016ca919fb26c\nA = -4212bf679cc00adb2ca502604b71dd5dab99cdfaf55ae92aee6bcf8b3b6354a384656c09eec6175a95c8cb4591ce118e783d6344525c25e5b356e45802ea3ce1fe764833132e6b7bec434e4481c9cc2986904988bd8da7dc2e31cdc481fd0e359674bbff524124bab1ba4379885a6cfc1b73d953e6d1aa1b938129d74fac9dc597c31383f2f7e02fd995f7065290a9812ba8e205316ad5bac6fc65c6c7310f1a6b033503ebfe85bf6d3851bea1b65b9c15\nB = 7ad83f97f40d5be508cb394c128764532f0aee9a108eb02840ca1c635860b6d751d5f676e8670e2f61466397e1bc68f97ea52d64b335d07aed22f20bb1ed19e3e42e4205d650e6d37714c2f80d39b111577725e3bc7ce75bd7ed5e44f8377d5fc2b97f05c3c1ed5ca1ec90ba3ff7935a25a8acbcb15fe1fc7aeaa1e444cc2f06c1e6711721d24b8969d465e4958cb87924b3e0fe99ccb371009b5b15747bf6dd5d0fb73b8fdf58d955c8773a55424a34c741406f6f904\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 909626a69c803e9acdca97c56781eb672d6fb31430a53b853f467ca26d4ae96c182d71c0212894b776c88e773acbe9602e3ca56584c39b5947724290def7dbf04c6853a108c1282def95dbd5bdc015b68daeea0ee959b35bc5af98a4ae4cc7486e627bc9432bd009b21ee9af3085f074a3ae1bca879e321018e991e7898f2897\nA = -14eb8e28dd04a159c576eb10578c24fad9eedd3d8b7560b681002a54a4bce2167de05cd061338f63c50b86327a79595a2dbfc1d3f4e76aabaf88cfedb69faf5148c61f8cfb2130511a3bf4a17d846ededd4c08f3b635182dff1854e8c4c48007af028e06f01235fc2becdb32adcb9e2058dcf8f8655624bed9915faa06be972282cfbf8530bc0cf2de5b2057df32e4a6cbc3c772feea0a511cfe3408a6dab0e2714fc4cf15602ba0da03bf0016f1f3f5ddfe1\nB = -388da160568aef9f82fc16f48a22e8d7aeac99121cfac9b748c815e5d3a823b673ddcd20c1168f98ba204df5e52535f61b224fc0374092f8c834321949fa0a812b5e65c492fd9fe8246b74143a943bcdbeba16024e311d673357a3dd3eaef9ae3a72bb06e03e34e091cbe5b6a9eb9fa3d7f36c03baa5c3e242f2c186b58db5dddbd73f6aa54aae027529b8f8f0a536b9b283ab08247b9977a2ac2d0d9f162ad03a2fe247d2c589b1a2d14b5f90d5b9c0a95918ea956e261b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 128e8844a2f04704a4a60cd33e85cb7ad373ff683abd167894a35a1daf947f504c0abd7a614e293ce10797a5330147c88c4d5e1dad1bdbeaf74095e3f5a515f2af68b7bc11ee1f53b493133905b654318dcfe73118ef1931eac47deb6c4958406b704ce027d9b027803eb8e639b52d5983094b8ff4b54e86a7dc6ea169ff1af4\nA = 75e6b045aa44dd9b8f4b434dd4bb1346fcf558a5e96b00fef9b6cfaca72", + "fe8b1672edc2a64beee8b959683b1861138b297629b44a0caec6bad2ac05665728379cffaf66a129f0ba40aab7c6b1c3fbdabaabc87ed3dd580ba80ec7ee765e9a8fbe845c0d207eee7a1a3a0c39650c75ccb6bcdae2e0d5149991dc3bf899ae9b7626a2baa17b168b260d82fba84a12f10e09234035e08b730cfc230f0d2651c03e34d4952fca6409b5c6ea5d8791c90466bdc4adf2\nB = 102fc193633b0e60a48dcc17aa76f3e52cbbd1012f179736a0ba7a102f8dfadaf434063b0ed1b1528a018b349eaf192fe62f868b538cddd7e8e6fd98b93147727d58561517b2836e4a373bb31fc8d5e42d16126ed80b880c1a37940c138fc1f7255ee0b7fd39b1b799c34e5178580cdc076ef3fbff65fdff7497398fb1cac75e5c09cc7df1168a20f88a16e7b3ac78091a90f1169bccd48c0d06b4707ab79b741a168deae5ced5d48bb5f5dd3f465e43c82b9db7edab24569b2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9aa9699d1e5d2c6acb21e31890c1899f30a925b834adb5b8bc8cce83a1718944a2c90faa71b34379a21340457478c0c43121dbd65d62e290eda2ba6230bce4e6f18555a1380c7c95c1700793157f7c1cbabeb09460ca28dc596bb17851ab2ba6dc6bf311ea69bdb7fa8eb78df74adf171d4677a154b8536f8104d919bdd58648\nA = 157fb9e1b38f288db78a1a0e22fdd9f48a59779487a9ada2774a094d34536b85993e7b9ab6e24f081c4cdfb64a82271100a054169e4f1c24e3957ae9aa8300e85eb2a45a6d5987eed4f0fba6fe8557cbf6128e018c5f9df028131bbba6c544b2c6312aeddc71405f0e4ce648fbab9e5d51685949408e4ccbe06fe501a36fc13ee65c31f062313135054b7679eef45964c77f5a1556ac09b11c496d0ba8c6057e283bdaebb4e6d9e5c557d975745f9f98a288d5bbe4\nB = -82cb6334479bd997c771e894cac1ead87dcbaf8f5006be5c70ad48ef94303137bdc45f261af91a201b276a17d884a56ff27af7dc06cc5b7b9c94f7c4d4a36f68f8d309c477b4969a6e7cd1b2afab9deec06555cb753d8a0eb00965359ef865a84bfa87b815a42b2050e1635d5ae5e3743c007bd79e820aa37a968702a960fafbddecebe63f022553cadd7a4d4fb27b4dcb981e8b490e80bbbf13af8c4412d158775db71f5fbc9986e7b8a8f9299574abf7bdf9ce7544e8c4e85bc\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 46e401989fbcde9d830dc6e3c42768999f153d44d270d4805c5beefb470bc1e82706aa7173b359763c5e15d146eca91a32a36f0a80802871933cc7f2ed15a5472988849a2d2f57543345b531538db57ab9bcbfbe787efb0a82e61baa505aad628df5f9e881dababb35bc2decff267eaed3d3671757ae1764ec5163b792b4db3a\nA = -590c16ea2cf7fa7f63b5cf74804333f22fd2d0e1da7d226da8425abad2b39a4672fcebcf5cc15d220b0ecfeec09665e682fff0140f16889f7a6ade9ec11aae3fa3a369b3fc133babe52e42b7a8bb9a24777521f4d9e0efe7d7977dced9e40784c24d2c6056b3b668ada7856da71af73d2dd33d2e481ddf40999d86a6e236d0d73f31a67c52cc8b38203bb2840c0b92c2612ffe5fdb6be87f9a787d70b3dd506f9a63d144db3417495f0a48523c812d14a89710d95bc6\nB = 5a2865cf2254710a1a51ee3056b0c1f6c5f77d22d7aa8f939e6f48ecec529a169e630c554bbe682a8c4de9ce4daca77a278d7e752cb678141ddefa75ba42e661885a82ab55d699414ffeb75802cb8f4e7583bec8a7ab58803b378bb60fd46f476ea490c9aaba568ec17f3a6afdd6f20ec54a512f7aaf62d2f941e35b4b72dea77095e863dcb38bcaf8777707c1dd437ef2ac6b6a8b2b832f80ad2a6d6f279c053d02058b1a657a1cf5b6b269e15d29087b0cfc0c2d4c3fbf32a167a3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1c9649f4540556ae82ffd71b2c71ea8588aeb845c50dab595db9f8faa01a26c809d30d8433b6c0add465e164cda2b6723c942ee87241eb7baf9944cae08babd8e22a0eaf35c09e9efdfb9f8bfa65d53ee6eb23fcbe1d12a66ae05e7592ed788b231b000f895d098a24febcfa4372d249575926a5faf966072f29a62a401ec51c\nA = -1bc9ae5fc2f6a3f1274584bac1e145f02c5e8c4779f4df15e98dd34344c988c1437ee4428485a09090d81b18606a6ea5c1b9136872ab5b37373fbffbb5b3fa8fbeca1e112b9f1643658c2f38b9548cd8f0f271779ce0acad403177057ea0a2af2e7435109879941fbf463488a2522b831b95c1cff21d2d816d70c25156369dbcf04a0e28e1d746afb8a77713703fefa512816fe73e203bb4c3428efe09b946b750199bd7a03d30feb90230c219a103ad4528cbe0de1e5f6\nB = -39cae179d955049f830867d4115d3bae25127c945b1fa0c16fa850e8fd77c1b3b9b7916b9983c1659b7cee77b7dc72abfff1c56681b7931c5e58cfe4f1bf0168ae32df0df8f652223885717a98f858a497b1a4be62a2215c39316c34451b0d957791f49139921d9ac8041899b8fdd5d3d443547a26ddf5748147e4c3e93f5043ede42f38a9baa628df65d3d6148ac2ce182056700f0f94029be05d3ea3a218b40f65a87b4baf097fce107c080de24880259f1046175db1297016af76d94\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9fcf6a47addfa336557749821a88ccd2573a5ce2c3094a17d9a29b33e043bea165499e89fd2c939f17a670694aff05e9af46836b62c96e597c83681092d63ab9d6e22751aa8fd4b9ea94a90a373876ef0f6514304a495edb5ca1795c9ade7965c70f9aa92f8ea460ccb670e9a62c81e9c\nA = 71b93fbad39b1c2755f2051ff7d532d59c985756410d58aed3947d6ae737ace5aadc35e7e0d29c684b9d4bec9c0fa277996bb30230f70431cb7b905\nB = 167be8381a3392dd4df62e150025e13b388bf366922ba8632614928922cc290772135857d1b5234d51c27862cb1a055c1b86260b6ec\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2ba940fc5165c6c5f7f4cb55cd89d1d5f59e90e78730bd66fb120a814514784879dc43ad4f355030ddb3486a59bc34b601474978a94ddbceafdc0ee23cb18708bdbd824d37cc32577802ac6057fef29a71f168e816309fc80cc46f251e7289c6a57fd222d5868263360af63dd73e7c8b1dd6b3f3b6939849580b9231940a4d\nA = 1220ac4bde4feca135268550ddc79d8b05ff72f483b39f77436f348c4f5360c22c598f7dfb76697bf6d2ae86c68e90748b8b729b25f932b2e5fd33f3b5\nB = -bfee56cd412318cd62e7b6cc49217345d3a94e7fbf6fa19053fa685efbc0f8b320b7e43883189396781c49371dffe7d126c032d1ae4b6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2ba940fc5165c6c5f7bcac0e449b64801e75134a390f120acc58cbee43888f50d07f7aa6dc2b33643c025cf745434d20eb1aeda8fcee5fa3fa5baf10d67c21390297857aa50bbcc4a29a6b10885f97fea60f1b88fc72512c111b938142ee8d67545efe386622162e8fd50418b09769b8c22efe54fdacd652580d609f0528bf\nA = -7bc53f6f2e78628678ebc8e35ae4905caeec61acca5c64fdf595689cf005bde2265cd43172802fc133dafd933d7b48def44256868d202727a4aa6c0cde66\nB = 74147c93e729707111d0d531b1c135453f3e59f63a7e082b43dceb8b16cc5debdb6d7c0ce0c00ec9b5ca51e7673e411c3cab34938124db6a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 43c47d7e319c32a758360dd726a1d91e2cf5c57f73cdf9ad2040e61a9c282a2962d96d300e04288461eb1ed37df19e6b88f104a250f9885898740f6487b081515314e0a217df2d4345d3cf81eabb2bfb346b634b9c251624748f6e9407cb677aff4c53fcf42cc027de267e6ec011e14bc7f3bc6666f693d21\nA = -1e6ce0b44105047d0da0eca7b936980267db41d41319dd5315889fe8fa2329023d7cf54f71ee179b5bfedf442cdad1920d311966f7175cbb953bb42ee105393\nB = -23a330c7e06cdef4b6b121d15a9c0bc774eb5e432e72d04c5f03a0c588e55e010b61f57c03c51edb1211685d8dfd2a35393091fd0e3ad2304fb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 768293c84c431b9c8dc6e538ca3f856c60ae5e1aaf42325865418b7bed16c7fc2589968319cf41cb370657c8edc7b969de10e0566b64ec796470b630e22477e7aafb38e99b6012f100c9d23d5517d486e3cab1fc60c1568c0228c9b55d2d77d23b1351fe37ad4fbf9c07f29330a539de4a32709d043dfc9e21aa1a\nA = 6bbaeec78b6a41818b7eec42fa3be7d639dfd86fbace2bc14e0369dba6dd3f04ede8b808743d809f43f70f1146dfdb1d649546441919e", + "27f1f7a9760da4a3b152\nB = 1199dc2f52868a0cf440f6666b576541c7aec1e9cee14c1d22010ab0f53fe8bbf3029c639ff78d89dce82de85fd8eda4e67395d435df60158623c5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2b90afbdafa02ce68d537ae807b4e7f3e05a66b20b84cff309941fc3150f99d083841ddaf6f19f5a76886ad5d853c73051a0457e95eeb0fe3776a084a027ee77d14f3825713a59622ea163a679cff904db33bf6ab23b06eb4b31f4e34fb122c8c170321164439db783e7bec1c265eed33f33bd9cb6d1611c00aa18a9b4b90d\nA = 1c4821515167f7073d4b7cfa318ead1da1131499c12497447846caa84176a9d4af576fe549fd8b0f77bf8dbebf6c395f84dffd40400101bf28b1dda0bbdcc5da255e\nB = -de60cd639044e863c6a49c73213dbc2ca84e4225aefa5f880e829f2d9cb48ae92e3f2680c462ac697dc34da38f65fcdc1b4d8c3c99e8cbe29660b539\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 33e8e8e193b4b99d8bb382c29c1fc5403190d7654f43cd77e28d1bf77bc3a728dde9de9a89c6522ebc7222d25f46833fd1753a44275b04485c77b675d816090280b3541ca61bfa33921a79f7286830131d6eba13acc46cc2c449b3a359f1cb49d67a4d0cc1245f3f8b59b1684aa0c3ff1c928b8e880a3375ed811dffc991fd1d\nA = -50ff3e00feeb2efc6df6387d6409a622b7a8297a717b8d94d0dc41c6ec6f29a8455c3580019349660b31dea1e4f66b74147de93535e671c853b604ba06a9b62d34646c\nB = 49ff858c7081392defc3ba12ea8869fd61188ff15d9339be72657b00530b851de53b1fcbe16034816e73251fe1ec97bcecd8bccc470373974287ca328af\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2c88dc40414969e8b614bf8db05fbc38fb2b7ce144d7e707f9f8eca40ae2309c1fc67e713a8da5fbb20e808ad20aeb369cb72a77fd285e38a7895ec0fc795ade4ef1f1680f3a3b3cee4569cc9d5e699984daab3385815d2e515ba5d67d21dd1defc12ca81bc8ea645f8f8d103b4a0a9cdc92eb50690c07a037df274bbd5217e4\nA = -167ee0fa8e5d8b569d7848b068df06f6baed80f6fa6a442f9d11d9712622b512249b92c7ccb821ac751fe4ec0a7a47e04ea5571c7cb45a7985749ecdd87f0c0faea01d232\nB = -2207fd8dbf2b8e9a5e3cc515479cde241dd3671803f9fbf7859459ac66705be055fa759c85631ed2a61139657eee7eb08fd963b49e33666e60b7e75dd26b5d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 674885ca3ef617a53eaedb9564cf96bcde131760ac541a81f4b25c174a6fe1444c2c206f7171e343e1bb43f81610162994c497419e75aaa25b664c122ed2b27640b45bf646fc5da1703fbf1cc66e10a3c306eb69ae5f937081a1a18dfc8db376ea18f4c1c499109b0cf8806eb32cb1f28985da790047bd7b32c1f67bffb9761\nA = 413cbcbbb5851a4ae12555801f7f80ccd888bb82ef1b5c31b99e1901d7e0ab91ee489c84044bc21fa2010f11aac21d0531fac09feb482fda579cb9f224c3149dd6249b0225a\nB = 1b6bfea70f1d80350eeb45f9a5cebda954d72cf5cd27a299ef5a42e1ed0b50a541d1657b70e50b0cab69b22e31d0944fd735957b1ff764865d9385af302bb802b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8d74ba5fdc67733ced4d468f6eb6ec4c1ebd79c97682c1d4daa06105788ed9c5144992e555d903804d7ed0dd9b29ef2648568ab7ff462a03e0bceb5482485afc3b91448fcfeba435dc587db6f3a022428d37fa0e85392d0e48e7d4ed6b21253084e653da8175587b3b709e28426cddfec8d9dc582d4ac2f3d540305c0fe17327\nA = 17c0b7f0e2cdf316e4d32f040e26d41dbde1e6689d98f0652da1c380daf5dfeb6a511b72d82f1b32d3852e9aa2f594be10776a8fc89a8a35c160e8e41b42a06a342fa1c309fd82\nB = -d7b7701340c5a358455ca5fa314ad83860d9f765978ff652d7f542de2e123bb976930b8fe84b9608648324450d8ed2bac4e44f2fc71711ae813cd8793af8d3796e8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 57e60f79b4e156ccec4c253e70df8d86e4aef326150d612a5ac4dc285761e88ede412d28d9dfa5a6f5c073d3c91a65ba9c86067d81f296935f0d0ebd2af82e7f6b5b336422429cc3b8427fd8d3f5a6fe936f4208362632093bdd3cec1aa8f4b176d260f605caf4a12cc011f3d1b76135ac2507346674e41673eb16c0f55d8010\nA = -4f1568c207a9ec970b5c26f068f3cc8019e8cb483525d251cd2919b368d072ac8f40017a19fc7437cf88e927c9e7d6f539ee84865f0af24be0d6d98fb33d74e3e0d28020c00bcd61\nB = 723db98a78f42aa45496f31cf78695583526d25e167da48ec310e447ad3540be2636813a2c2f7b8c622795ac451992e91bb8e43e5737f0dd95623282e729d815b08ed8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 237eb5726e2c628a515104bafd44348dbf099569815784eca5d6a415d3c12421c8c70fee23d6d82f7b5b136b70ffed3b6d9e98cb47854e79239d96c26f2ec955e4ea8dabc29a1b0765c9b7af6ef09ca673d1ee21c680e4b8cfebf47bbc74c993d017ead6cb6f3319ce4de9e9765cdb3ed8fcc57a1b153327e1a6a965e5dfa89\nA = -1fd1f634685eb1470dd9080529a891253a28a0b31e15c662733e20d43fc4cd71f4cfe83c3774adf8293a0fc3bd806d0b31b61c6ed0b4414ccdb91e2994e22797e5771c63defcc0887f1\nB = -3ec0478afdf54c949a097ca411be41f931acb750ef4f0ce97d0f0fc77cf15970cfbe24b170aa332de04836b7a0e6c5d456814182d27c8310d5fb662a818bc421587d95fc5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f1d500443fc4f4b86e7ec93e4d0dfd3faabda35a6dd31445021928373be14c37fec369ce80ebcb77aff2151b7ea94d21592da1823ebfa0af196f286d7a69ea54799573bdcd4d09ca4f33b8a3a93b35de5ff7f65099d59367914f1c79440b471ced6773b0802bd8ca99cf531b62892eb1e78d67f8210592208859b0aa1754b14\nA = 572de2984fe2ed0d5ebb5bc3f62b197fd592795d91cb16b48a0c898991ee3e884e5870b92405f248036ef9b3898c5ee6100a09ede5a48bf7edf3a067e4fc77e7e6bf6a6e3d4f538e3d66f\nB = 12c379402b18a34dc8b80c0dcd25be16c99d6f76d5d64b6050b90910cce594bc022794640735710c7ded857ebd44fe5b2e51574a2296f7d7a61b59c0123051bf2ba4a168cf8f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4001c734e1391a88640007893f167eb79ef61e4717d5eb14b8d80c25ed59c753be63fc8e54bdaded22c9c7d3e49753eb49efa010439807dba0d90ec4f9b498aa97f109af542bb41922936223213ddedac4d0fad8f1446498f4228b758aafdf1d9692f59029c76ca2832125ba50e811cb95f2b982a7a4d87b4726e6dd8b1963fe\nA = 16792909716b581a936287d0a8550a1f3e840935f0f3ddca75aa32e3489269b078fd19a16f8d6b2326eebaf46da76e90890c0ead3b35689bfda8c1ead17a4f672588f982cfd3da2c2b9bdad9\nB = -95ab2c47f85001aa852d6999f29644a6a55f9e4e12bf905f911f90d29cd1e4fa4fc9d1a2aa6c215bcb5c5643561499aab8f2678fdc5fa9c6ec138aeb2d62f635c45f239e46b0fa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1bfad44b58d3f8bc987116d4cc7ac98f89f838a8712d81d726189e9e1469cf46fe04675dc0b82e6e556b02c350ef4e30ec6203c7f1df937ea80f435af7c10f48538fe7755ba78993f304e64ca0d783b0f46f61bd14fd3fd30768f233c59018ce911a94b495f58eb96438e416ca3c7eba5b1bca9dea5a770c1d2d9f2f62f821e5\nA = -78a6a6ef40e443c52036e75f0b35938d632bd45aebf45a1fff5c2e1b6f601a57382b9a82c3e8b2984e643eb1570cd83f3a6be6daac567ddf9f37bd96785662bc3cfee6f47503d239c77781a8df\nB = 4920f870cf9f371050e64a419ebe07ac92dd3525b41e8ecf6", + "939a267e1ba853d54862dfc95dd21b3526eb0a0a7a7f8fb67df2e9472dbec81e15cb13266257177c5f2b92fced4cea5d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6b0b84505907a5ca37abeff9a5ba169975792c69b5751d9845c0f09dea833fb679c8dfbf3895bc470529e0cc736c9b4a0d08b75d709a1d04525ae583c5ba082d3bca1355055c7bb674aa1b92689cfdec4dbac84a96e81c855280e417f60e7e4931ef4f428420c0b85d2cd11c1030a47788d6ee6af0a76b5364fcf23b270e9d4f\nA = -143d843e3b12431fa0d873815a757a214cf731c298db61ab13cb87fe78b0a6184bd1fdcfec0c7661b10775b4ee2c815dede0ed497977c9ec5154f7b24a8a786501ddb8dd257bea51b9fd9401ff760\nB = -25d4da7b64f439987eacbde66abadf0da7c1653c1c1c6d9b2092351fbc714a20d2d7ad8093209da371150b69b3602480595533ecc1f3c5005a8ead10732272246d8cdfbab87c49e65223\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6bce40524278ce242b0b5292d27751a3dc414f962d9c1cacb45fa3ee693ac6890d2ff1647abe578c40ea8d4b326a2e0e2fa7cdec28fe2da089338b5fed91c4277cc5be37537eec2f17edbf48a45fbe38f15c58c3e733d408d001262dbd40c9d246c323e7978df4fb7207aa9270a12921743cee2a483e7e71b221b09a6b2c667a\nA = 402671b0cfe14655bc650bd35dd0c36ce7f65de274a0cc4b708c6f6c3e84c2125ab2430e702421904950b29aa8a03b049910305127890457cd0cc97a3e05df67f29d28b0452969986959df02f59d207\nB = 1648c29205f19fe4c646eb62e8ae9b65260c2cb8424a526423c6bc04ed55870cefef9b8ba808f8ed2e1ab170e2e411f68b934abb1a22776969f79f9420f8bcbef28417582942e26646af60a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 40db38dcdc201648da555f1062bbbb92c632c29b66902eabf90d98dec69ab3f3b28e60cad1571e7246f4c9e6aa62ad26a6d0bc08598c7a8571fa830cae4c2875c5c95a59f3295f998681edba7749b7e38cbece8887a7823b4752165e1a897e638836d408f439f009d0fb6c196e83e83ca3289d2bd0f0eb36b721331e4f9f80fd\nA = 14361ace8ec5223bf0165b78913b77ef921b7089bb5e28891d120bd3db6513ddc90404a4e6cd027f9b51fbc02e80d376d59e1f2b043954199ef8218bf26cacdc5e749f668ad3b4ab35cd796f94c06307e6\nB = -851a39d8b0101fdb22ea9e367286e572dd132b8a77a6a14dd0e995131467aee898230f37dc6224e35bed2eaf459aae579181a161450bd7ebe6b62ea7154a8a0ab590ca4a6c2f05531c4e24650\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4b085796665458b798f824d1c1a88c23ecca456fb88713b433228ca8735141a616633ccec4bc53ea4f6e0c74e4aab6fece2e4cc4c4efb479638cf54caf55d4addf75908076f5fb487ed00d540e5b984acb8f81cae3ef51db926a06382a288092b352793de721c23c371fd0ce7a789486b2e8b867d35f47b5daac2d339d22dbde\nA = -511565611538828ff7dbc45c273fe46f4f5105d41ccf5dd343b41e9dc579429e56a9cefc54657ef0422960d1375b72411a5cc93ffa323455e006e242580358d6cfb641f46b9c36fa777a613b17dd4a187454\nB = 4f22597947638b9a9e9b9b7c2a8d37f77259f1bb1c7db65003b6e1a1c807469c84c89a75b80bbe0324fc3aeefaedc6ad9c0d9e470dac9c30bc48f6abbbdce9547ad7624f0ce9ff3cb6be23e47bc7\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b90a57349ea94ea818207fe15c164f9d3530c7cdffcae178557274552f79c4ab56acd78033a570bd6c3e45789704ef0b0ef586594fe4cae3ccfbf9ceef46e769589b084adcee3ef8345375b7103232465b991273df724964248737d5eccbac558e35e4190112571d3e7c291baa7aa8b1800121bd573b8419f627c0091e1bba8\nA = -170cc62ad57094d307ce1b317ae5e825c2f2e317ad6060437afa105501caea00dc9a86af8729e2f3c3a854387dc3ba368c0a84aab1a527ab34fe27b0a69bc71c728cca87be728457c65eea7d7538ef3aa282615\nB = -3d9da1377a88f647de57ade46dc7caf71b4f42bbfaa5e77f16cfcc90f00b5d3e9e9d82355104c7cd0db4c1dac0496be3aa35706cfc0a30a1329755faa439694e8e9b41fba8f1ebb46140818c7008e27\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4cd4da762c7576d582572d3427abc4b4297f740705fc14a32b46347541b152d0d1e3a11f27213badcea1e2009e34a63350c7a59e4d43654b28298d2757d6b54c4d82f580e98de4230cd119ba350416452cd4b8adff29b9f35ae0c533f666cfed716838e2b91941dfbea8d6a978a369d5f27554ef411f15e5a89850655d7f3f5a\nA = 4f4a28af27b926d8ac347503d6ac0bfec388a6c0b38a577501c3ca4aa709c69601824ddeb5eba4d9e437a97f3e4477e1487d5ce7b4a35b90fb863657a5b2d901bb8c3c838db40b89b495ee9875e8eee607d7b8013\nB = 13ca192603bc8b2da29dae67159e4f8d32f351a503434ed9e4e24f74abb5908ef7da80781c71b1a5ce64fefd13a16cc1eab05a370bfba2a97e6cf90cfe98d3a487ba72dde0762c36c10e1da175f1c1b5fc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3812e9e835ae355fdf328b29ed8b86dc3f6895e379b8b5d65a5de41eab5fb20ad3e2290c8ca69f9500248ff883d9715f59d0db6257d13c5cd612211bb1fb99867161daffc77968bdffc1fe48bcde0fcce02ca93975b3cd9e93b56974ab4beb59582c3d0ef2a65957f701549f8bf858de0c5bc98af3e5722f1450de391876a2d9\nA = 14ca6101af00d67139b985ac9f149accc260336237dd2dee802b5cc6e506e217b74c1a007ec10c20012f071ddad34e7407012669109ec1f385566ff04cf1a1ab7562353c0af1ba1be0baaef920a188c60db27970f64d\nB = -94b683326e9de19e414f653aeb2cb4bd7b17e76a23de6a4d91c43d717a35e08f2155b444a9549dfd01a8aec4dc901ea9f629f16bafd2c84828b12d2f63dc154323eb2d54938895ec4c9efbcaaede274fd4ab\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5ad7411cef0581b2e675d03b0ecb9969102a283eba5e779bdcbb7646d94e843083a07269c932d18b973b57abe54eaaad0aa76cf7b61f30505a263bc95aa063efb264ae829eb1d1d5f7d380a0b4db59839de9ae6230ba51901e71b3e3d59e8c34a79678e751c8b7ab139123bdb2f04d90a18ed81d2046ae86da1a73c8dae4fc4f\nA = -469f61cbff01f0e4124ba69a860ec6dbc75cd758dd8ac7cbfed97645b16488a329adee62d1a66e90ee4212569d56d58b61676262f49dcb68296bbe5d8e23853e3fefe8a304710cea568ca65c183531a992ec5b4d82e226\nB = 4a0d48e31cb8c24a3b2c9c95fd19edbe46823032ef4c97fe65d0a30d5c2cad7a4fbbe89e0ebc9940ed9f9ccb8ab18bac269759a9740a7985809d0f38259e680f0703febe7fa012d1ded47f0cace4a133f59a721\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b2953981db406ebc544c39dfeb08a8b089064533221536c7fa2bf2a7a0d3a1192859b7dc0ea5036eeab5aa371e3e0070c3980433adb3e3a5202ff257bb546bcb9550423201a35501fd717ed4c0016eb3a675ed399340bac7f058a04e69c1774590fe747ffb9c27e78ba50fcee30ce533a1659fc49dc080a60f21357a6265d24\nA = -122621d97f42b65b060c84df3f0c0da097b5e240731b77a37bb9471e7e398b242db6f1b5e25062a9bed702860ccf6aaf386c1d6fcf60fc31b8c190d3486949c5772b9e621b863a7cbf29449ddd68b7e0c21e669492e58e94a\nB = -33978406dd30ec2b192c416e422428683deac210017cac9e4355e8446d6969295b0fbaa8cabc92c1fc0068da70efa047f938a419bac160ed6f794a9f69f53a88648c9725610d5f309b652f5462bd3011cf68ea859b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2104dfef151526e072c09a4a277eb981a035379de", + "3b1a55a88cb060681706f26131c388f5572c5646826b119c85ed450207f32733487e3c4e1e9d701a65058c4b4ef0cd1db090495643038229ed177b54695ac32110619038f1c1cece14faa693d88476e3d70329b0084d0ba5d547bbaa5b59ba1ce1fad5aa2f1c11a75bc7c0\nA = 7b79e6f1330fefffaf8521089c3348593e40ab7e8d4da3d4346571b43b12740958336580afd13619be3dc2d42eefd9e30599405da3e32e7f3a5655ece8b77a367059668021aa092460de75e627526da08e6206b0f8f539ef40e\nB = 156e234931907c0c0970c1fe6bd4b24225ed94d5f5b1be4693c8e141e9a6032425b4a47b6eac6265afbeb9d796eb230efa707d5ac4a73808225181cf814b319142e9d175ac461c75e6d479bb6bea53954bb981062eb16\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2a392c5fc96c29df2f5ae9eaf76e7d981dc1e2f3b47b43a98eaf556a9465ae8727c622188123c64658053ec50c25e54ac5c6c8bc279b134d326e911f14c873357647866eccb4f9038ed0cef5082c2058ebd71e1619f7c8f8f2fb80871ebbca3fbfb7845bd855d307d2efd853f1bfd467fbe030862f165e53a9cfa633d0d3fa23\nA = 1e0430e7cf15173d00592037e83e717c90d7dab4f54a5b2f0f5772762fb5f56bc0b2a53ec1bc3b960afc35e7b043f9d85d0af6c29288486af3e186e52bae6300b58917647231b40a12648cc8c020a797683a9bd7ff34eb6d41b928\nB = -e08372fc766eba6e0ef55a9149d700b503e2e3f978c8a397912e2735d5bcff69c461561ac0822c44160c7c1bbf722df421b74beada57462ac54a9bdcdb42d6a27b86413036ed2282abf62800fb2518a32a4a135bc948053\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2608f68632ef14dc3979725c8cf1a0db10a1651f17d91247edfae9935b53f6364d233b030eb99871a87b7bd876ab2cfd5a643387a7af9d337e81770db04a14f4f8dbda2cff604838c9af9a31e8dccf9277d453176589ba33abf77855b9501e63370b2e6cd22831e1e70ff1815302c0a026c70042957d08e74dfaff940a91a7b9\nA = -5d3568858c05a15bc9777af949eb01d33dfdba58439fb3f7af2ba792efe8e78b16d7fbc2a303a4c4c4be7c9d43f57405e88be54d6ab55268a4739945ef582921d2877019659dadbc76e0939f4b2cfbc91e5356ba2ed531526ed5b9b3\nB = 47f81f65ea1af04f702757c02a175a299b23cd8ad551fdb67020c50cbb4110b5371dc5790b12484e9ce647eeb24c0220a5e62aaec3461a9dcdaf1a22814b6f22d66372cc5ee31944bef33469f905458c172ec7871d9dc9c301\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5735109bd21d31b5f54e9221bbed78c54cf387e39c13d31557e8173e173f786b2d2f1acf3966c3bf4552fe9bc802d0868a5a7632404cb91609a7a45fe0fb83fea8d83b0319666c1b0ac520169c15be708343359447f2fd37960c1e96d32799ac9394e839b391f59dd347acfb79bcc4e34e76490880d163ac97ee69e3a0a6e68f\nA = -175011349a0a1ceba11756bd528f2bd631c106e709aab223032d08d52d7d6724e8c5b055b6f97b48261f4860eae297badc1214cdae9b2500a7a47b4b777dd7b8f1006757754ff1143b637d2a3adc555f38eafbd5478cde0b04e5f46d3f0\nB = -2aa7f75d6801b04ea9f690aa0c5448906595fd28b53775059c01efe54b463f1d87c9fb4b39cb038e770f99bb995a2118b86ff8d004bd964e958c2af82becf362fb0b927c671cc3bd7185990419d26a827a2d81bbc0126e1029556\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3b4ad19b75e1301d19b57ba9b68e0666c28c7c5c99df1d5fbbe0685dc1d3489ff39c919222719c5d8b7ce2d7ff967730d776a02b36a86064ed66a02011bab82eb575390f85f0104715f6e4954a1bb28518450182a8ef58af35d00e2fe417f07ba25dd9c85e00c3451082becd22e3aa0c9bcedaa96e6423c7df6c375b4c799c65\nA = 58e1ce4a9b512eb0632b02cf1207936d6707b802140540fbcbbdd712e5ac1426b4f36e74a9a9ddc812e572855d4fe4fca8a0de6644226f5698fb46a5f2a479dfc8b588aa8e02ddb15acdc79ed3d17143e290f1317274f425b869df54a4807\nB = 14e341cbb5f5a7f3b4dd864172b82ceed2887fcf20aae7d0598b3d8afafd2f10c27bc7456c1488abb570be3df04f43d892dc6a8dbe7621f55bccb0ee3acb1ade989a510b4e0cbe29b6b93968f323f0016d87944c908824d249769f8b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7fe0bbbccad6032069b1a335b3f2dac16089051cd9321f903181fad23be6853e2d209958e8c48e008be94a62c6206b34b4e994ca08b8f24a2df0e6394ea65b3b7aadb3bc43d04dc9d35a77e673c4476dedefd4568b4ade5d16f9d89486f3d5ed0566b1eb428cb0b688f10fe3901037744f278385754fca481f937cb630f60308\nA = 1cc0e3ed58090db55063c9ba11401636f89262d6ec096d361f448496e05181c5f7f2604333f26d511c13534618e90637adc807d622097f7eabfc03266135cb626e1bad20997e72da71bf2b3f65a4973dc27d2a594b1fd96b7bf7ec14b9e4b983\nB = -87871b2058d33cb67d83b6a56ab27839c6a6c771bd94e55f200a1257f2c737e39c4a0403fa410ea64e8f442d300df1c19c2f03d07fb74d94f86d26814fca23d4cd2cd3718252cf0cd8a0e36726f6e68827a1dab6bbb1d23b884381c702\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 35d7ac5cbc7e6c262ffa41be168b02a3bde9e112c512d1f68421d705ea34461ce3e0dafde67f44d44cf31d91b38d4d5f2fbf8c6c6a44ec3ed0298dd58f3d45c04346c11e57229dc3d2cdfea02c802732d9a811d7be5e81094d72172cd04caaa3c9d55a951c09f454f42add6e89e2d8a98e124aac86379df377606e7af9bc6baa\nA = -4ee01518f6581c560a186fa05c6f4bc26809c4822cc74a0bb74d5a6b0a368aa9bd0108f26113443422b8c589084ad49f919a9e7821d99127bb210670e732b7cdf610e464e300a39d3dfa7c82f90cf00ce329bc6763d7b1d4224a020095112fefa7\nB = 72dc8973f7af7122a05c90df190bbf1e39abca908c197590dc7ac41fd0712f48f838ca62a72a177a293ee6b2afa7a10c21e7993347c3df4f161a5641ff62ba123999bf1eabef29ec0d33ed0919818f4b7c35b5f41e654759fc9abdc0f80e7\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5d83a9b34631dd6c63c05a0c012adf97b4d0f20f61907e1c2145330211e9a7e38128517b058e0a85e993c385068d1cec768deb814bea1323dbd333de091ad2cad72431f20c1e70ff7e1b119768ba44e14292c38b88dae7e55ac9e10ff98e9bcd5f0ac05af499196b4be0c6222d1a63227ee895fa6a8221a4a182a1323183cd7f\nA = -17b3e0c9288be15fda58c8fd228216bc466731d631218a7ddf1d2c9cc858c0219cb0757d3b680bca1b1964eb15031b5b9d761a8bcbd160db89be339067a2ea35e1ac3cfed701912a17ef9ea03999d92e3592e893183ddc05cbb98a656983b54590c72\nB = -269f96a4634eb37cf8a6608408128587ba45958405a29827d0d03d34816fcb1a2297f1319485439d3e8594532545086efbe4d21d31d30e2daf09b74fa8cb27df54e8f9f993630cd9a292c977eee70887158bd3fa3cfef321ef900a0598ac8cea\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7fc1c65eade94d9de7440eb8dfaecf1004905135efd4f98257c3295b1e76ccf1e2ab6808d158d360b7419c6210c50efe960610973d9ae855c72ec0e81d423e5863c80b542ad455700d2d0dee5fc403dc01eab460c24687401cf6a3179642e59f2a30268df95fa80dcdac230702352bbf6b60acb9ff5d45c5b09a3403b954d173\nA = 7906bd8d3bebb1303c1df1fea0b2503b0abe9c69b4f4f5bd01eec9e314788cb7d44b93428adbcef570477e8ecac2a64822e481bdf520fc381e1bb0b2cdae2fe94e484cef5236dd524e4dc364b72f4c06d57f29dd3c5079e532b1ab1e71dd6a65b3362df\nB = 1479ef2807b9c23c094d0416f513894cc92e023b134f44a5333360dbbe98b8161ab899302f4fa11b470b97dca0c4e8ab7ae47e5fd0962834e6cc1763618193f4ee027f667368da580c623080de137b5869c3081128e6081b9d5e2dbafd791773242\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 730c04094b1ce944588e8291f7e6", + "cf763c70b79cf362dc8a1bc63bb8790cd4cfe4eb51cf15a45a8464d69ddc3e1b9383cfbfd643f317108cd9ca6a6eaaea177c5c8b6747bbf40108cbc0437eb8f11bd2a0939da59b70c0c6129e2c249823897f2ee536b0427bc45035f121d2cbe7441c175899b97c490e6c3ca01539bcd05848\nA = 102cf23cc3b81785c73ac3613c816de47fd585c7d5f175185818dbb4bf0bd47d0dda9702bce97b29d66e48bfaae0fd07b47b40be2b48ed702ef21c54b10bb927f9d6b43604bec4f4b2796b44aa6b4e83f8bcd00f2fa3871dd901570e1a32888d8691454c40\nB = -cc5349a9c5280a933e87ca38ce458a711c71ffebb40bb1f7612b42b4684afc495e99c4a5f32eef1c9564c2b7612ea4cda7a0f5df6b3ec9026447dc565ca08563d46aec7ced9fc4cc5645960210d44cdc3944149051d569c9295dc50862f8f6d1f6cd1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1cfe1842a53d00e4619265e2fce7cb566ffbd912c9213925d01408a956af304eacb85e29fb6edb812a95e90769bf1c3d62b0cf6cd5bb8f8992391d2ad70f38a14fb9d1d1eb522aa7b7fd9f1b52790beebfc887193882377b7ce567d317d8432e1d9a908d6ccfe8d2de7de497d77b023b3959cc042ae30aefcc0229617fd2a146\nA = -5c3d24fdb193ed83f5f6a825c1716f98e3cde6b32e09659f253ca3fd2a39402b5bc3a6497ed7bc908838e93422559a13cf59156254bd3fe1e3b8600b2a777943cdb39b9d42c58043f1d587424425d3ef5f5538ea157112970ce3e09a87fbb5f7c96f1b5e65fa\nB = 675d9d2a05288b438ddcb330acbd59e4639375f3f14ac2d0e9e8b72de6ffc1d217ce62f997577f7eaddbe4603541b132cd41f2f2740363d9c331ef22df92029d143fc8495ed0152b918aed7ff22f564c7cd94fd3fe4178c90365ace43def8fe30ab05c0e\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 83ed1948276d689bb7fde814e67fcea72c4e3509c48873c3e7349a8fa1c08ae11ea4d814d8deb1021eb8b8ceec342cba5002a2ca45d5f340ae1aa500af4c7db120d0402c6cc8a840404be7221bbc46ffa10236043e5ce4415d3ef1355bde26d2d26eb7127326d4b8d671bb96a08e38a2c1dcc281830ac77202903a5e4777ff02\nA = -1be86e7c87827922d2e8a06e3cd6b64ac9a280c525749bcdbfac4856916321a964c9346d17465378251e6eada42dadf38bc9d7d87367bec94ebdc21af6b1302e520db08a64ba6b39920683725ef02b011a3e4ba46ef0eefadb98582cb911d0cbeae9c231b5e432c\nB = -352059faf97b433089a688c702b97adefd0c91d51a0395647f822c6762fee3287693e302fc5a5584a12c048dea1a320cb96fa70b5daff7c2ea21d249467d14c6bbee15a1e94c030e908342a939fbe8ae0de58cb6d6eae7758485e392ff6d5d64465b701692c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 402525e19b6b68942253d1a51fd9b2ca36fc84cf938d80b3d52fd4302de142b9d93d1663e89340fff10c2b5efc8cd47fc3b5cc5ccd49a6ea3038ead6454bf190b7f88f52c56bcf00c6ad5b0f5dfb7615915ee8af137dd99cd3d21172ab772f36d291a6856a8e7912750139c09aa024b930a0a6b9eccc83c2c5c0ee2473ea32c\nA = 65e5db532ecae639bd56dd63045bca39b33b4d70b2db82ca3d0ee8ca436e671828cde80217b48eae7487fe110830589ab1be889f1e1463f3b0757d529b2f0cdd2ac92c35e8ec141885bbefb6040a3b5e00e64a541913a38fe05824a929f8c5a2c46568c61989c3ca7\nB = 1d9c73eef8373cbb1e8393feb26d55c33a245c33d7031c234abffb2f06a1601f7f3a79ef1e8664c51ce5dba5f5aaf3b9a9e42470d381219b4616ae93c7f6e64792d23bae523b6a224c1f714ebc82a11f9be42618922b8d2eb7b55e4d45572e68a19fb0ba72228b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7a9cdb5dcdfb6e04351057d731fddb9e85f41eb432f01c0d980673d294d05ba9b0180133a89930e74cfce78ed54991b494a19e7f80f310b85904784cebc5639bbc631e80751807868e7fe16719e8ffcd1f2cbd1b9f303c3ed488b647670be3080668b5fa0e53b6342c33c87f0ca1efe1ddb1c877bfe2556aeb61805b06f41343\nA = 1e412c3d66aea2c503f3aa5dbad368a61d969a2951c0094f9da32d2794e47f3bf4c481ae23636baabdebdcf0753d431426b1865e62de8eae7238a9245d62820ad7f17b5380d701f5db776cd4e1ddbdfd542901731ffcea5bcdc247fa9c83f7e08a9389e5a76d38be21bd\nB = -afd61df72361260484fade8b432713eb740df83a401d73492883a5139c918d5c911ff5dc00140637da1c6acfbab4b0bc8fc1f337243d90beeb1c2a083ad8069494c73a99372bd38712a5b5393c779ec1915e878600e0b48157bea44ca8e97c6099c4ab07fbda57d1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 712580a1ffde78c8cf98ba71843c8130e835fee3afbb45e372d04c04cc388e403c9efac742611d7974bbae982c3aadfd1893f5da280afe0c1db1d81a9ed73b6ed9b7f05a20ce828316103259112d7754560d66733041e9470ae0d4dc95fd0484bfd56d66739f38ead7efa4051187ea41f7bea8fe5d958a29af41328246e2bc35\nA = -47c5755ca61ca8b7ea927f6fbe347f1362915548ab38c40f0418f4c9ba4ad520c3b2469d9ba3976669dec0b278461bae80eda53e9d11447512963e797f45460f74678acdd69fb9efe3897913b6568f8e03a6d90b4cb5bfb06af132bf118574b70e6bd2f6d6cb4d0089379d\nB = 5bda68c0a64218d3609d75eb4832d5468298f19498507d7d515f4c410f04dee535947571a5e75f1af7f94a5b3b05fb742fde23e7cf3f8b3dbee0a569e5a36d7a3d31a26c4a48a299044fd72339d2cee1a68966c851e76b93ae34130b75f4abe4f2260207d2254d23f56\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4a1a514aa4d1ada84fa841d0b668930c904783fac521377a7d622201867d773ad23dbb667e0d4181616358f3cb088cd157c8e72bcd03db64647b37aa1813f870cbb0318ae0a3667f8e6c19f6e0706217646ce633f0cc8bf4e8f0f4d7329a8647252ca6d376416d545e73cb9a3cba40f8f9465d85d57c2481b84b6d95dd42d50a\nA = -1d68bddd8c3e6b78daa0acfc63a6f39e97f19527a43f6cdec47568d57b47f4e4b7ee88e4a28d683b569e406ecd2510351dba25f10b9f7c82d6da16d848bb970cedf7675e67937921bd334eec4bc8fde83d67aca57eec804ce22bb342167602fbff452d5f0f2a7f38b576e1e50\nB = -34d219765916a4c8ec843ebee9a7aa1162974d41cb4d6b60532513608452da9993749455d9701af6b7b6c7454d7f2fd5c344cc938baa5259301d4b56ae8d25b6f6510ae6bca114cae6791fa5a9551e8a405f5b1c0bbfc27138563b2d64f9a4d7a8f42a23bfacc3f1ec9393\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3fe24e66e381eca525b24cf767215837019f44ed4fac6ab118d02cdbd658066505ee5b0feb7af51859992ecb97d727121e38873f748a61d70201cc43228a7732156a80dbe399e05764be19e37dc1b93222bcdcbc45b1a4817460f7021dcf1d70e632bc6a306628790201222bb522f4cc80adcc907463a539b02f74004d42adff\nA = 773454a43f495959dd55b8a064d70b1b1ffe45c084f5f9553582e24fb402b564de68e5379a8d9d02af101594e717a6c6db2e7173e557a64d2f28fd45c4e06041deda040705d99acacf8086830af19c7ab5e27f91738ffbd937dc27e5b7869bb6caa12c2d7930366ff75eadc570a\nB = 13d884a2396268f1a8186748a15722156a172a56dd3d8c77b9cb7001b6ee06720653507eba9bb9918f2f699cb37f3b5ae514f5180108a704647f19b0fc075826153edda66dc1105c1008ea8ec6f8c10057f8e8e479e1a1274edfed9ef719b30827a30f26da78820c3696d01aa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 715bab8708e53f76d2ef2afbb845bdaaf978b54ce25f84dbbf9074f16d30a18733a02a4ba5d7b092fa6c25d3b9b0d8243c743910f1b7b785d9cb02343fc6d59eb0817bcff05646030ce4fbb2b9ff76781cb1af66b46553d365d02c61e677ae97defe92d057d4378dadf8cba9824b0022c086e0d78b5442bf3d3263ba22c643f7\nA = 168186208c734383d472374fbedc2d5d430e85690a4881b740008623120a4f7f83b2cdf85dc28bfaae5870abcd7ff1bc782ef11c78a75c99d41f8aacb52fceeb5f10266dc65eb00b0868937340146d8850887686d54218badb97647a6d82c0c6650ca1f9078d73fc6222aab95c2967\nB = -9711e5b3965654bd9427f79c89a0b3f3cdec1c857f4451eec236c1f221bb6773e5dcc30e7381a18a", + "813ac2b03ff4a4ba679aad41e0e5d7181d4627f682ca2dc8af9a8b4f878771446fb225a979ef9c7e641cac819c307c8dc50d9c1ebadf912ec7c844e416f95b546cf09391f9f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2714b99dcde70d6c3be8b671d78abc155793f13105fd4b7c5d760a4c68ae89987311dabf2a9238d18299f983b8aca69a9ce398fdf2c9775d90b11b3dba17bcd8edf661efb6e9c50b4e37553cbecb54eb214fed1d0847287732810e550a4c86b51d4e5da1cb7722ce4317e69644620ad806d6d1c94e1e3fb4d87de6178a997453\nA = -75231ed37f1dfa4487c9fc79a6f7b36929fdca086e42ed41f79430b2dff521919236fe415ccce590e1d3b986e16dda866f3f0d29ac1adcf55d87fa5cb67dbf4693293188516e360bac513303769c42181483fbef7abcbc4fea1310c916396d29f37d9058a62aead94511aded7c4b8de8\nB = 5aadfe65df0e5b877fe45d42d7ca02882cb6c686d486374da5ece6f87771675153c84d74b6f40df1db567b7e1e3c60c41d21816f958f5576fd2ce2f84a8c3be4749dfc7e5561266b7c9698c7581292d0d813cb77955458d63bf94ce87472924c4ca79504d1ae9d5f025c7a2504156f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6613b1c8ccac0cb8fe2f59e76fef4dd05acf1f1b2bfc20aa3f193622ce3e9d4c7824ad544477553bc68f05f0b546e7c1ee87301e111af7929d1f40525291b88e211db7175f4e5c0953141914fcb4fb951dbf77442e7cb28fde495704f1b5141de1e50fbd0e359d0d86ad709c8f564c84dac81c7602717c269219ab1cf12e809c\nA = -1bc03897b02d1edb633e2c019e40c20c1d89a210b0733412aab675563fae8bd75dd7e65988cd8df4d9b343586e27f548becdde274f62dd421679554ed9eb127e527a69d69fa8b17aac0424dfa2a7692d1e63617ea45564b55f01a70325bca050862d583cdad96c4a2e123d0ed827348a745\nB = -3d5239dbe7bb3dcfd8027204eccf5e9444e68d322a0b0c535a203a1d0c054e7dc1e588bacb891388241462a5d2b43e6cce34ce46a23e6ef29670603d31001374dfa347dfcc794988e58945d0d2d17da6565cfea559203dec119fc357d396f65b296deb07686b0ad2d25a13fd4fad88d2c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3a7fc5680aae875b9241200b9f4112a82cd624ffd9044138ae3cd65200631ee9d7b918fbffadcad7e598791a9f0bef3e23005d6bc0048ba92461283492df3bce74c66e417b082ee052fd8f808d71f3ab18f9ffc40f8fb51ebbb936d09c26a3514bf868141f7cf238c1abb3d88e5d50dfc188902254f07d63fb8cb611ef8e4149\nA = 4a30f32d467b29dc83b40bca2fc4ccee5f08a64069cb87f20e63387b2219b12aa312400c4ca59608f50a71d2535cde40a6d248290793fe01693ca40b93a5cded2dcfbc9aeb36e187c9d650782d12bea917daadbc6525f266e074037803e4b2f300778ca8dcb304658cdb502c93c94a16c6261\nB = 1ca5e5218dade077fecb81d579e1c9290431b34df5ec84aefaaf233d68f17dcf60ee010db26320685af13a821b6daa9d73d8f3a30826c3ae7b2bc5e219cadcff826283cd7dddd04cea7a5e0585d6e7c9f23b27f14ff815fe53bcd75fe700b1b91671bddaba737fb43bfecd2a77e5b752a206\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 768d312175ce7d2601f30bb38339f046e4c2ba5c19ae5f7ca5a562cc2462c579fce9985e9e8afe2578db542c8d9e7693e0c74ba161334b249ce720d568e9c18f09c87cd701e6f2080b752362f2fe6252a1d0caaaf1fa18199776e4c6078d89d520b9c63db159d5fba7e0838811e68794b1413c248f3f7173ef29eff28f15b656\nA = 149353e91bdb70cdca8f06648388508511a64d05221305cad7187ea40d9ccef91fe17ceb1e79667bf66e8e6b7a57faa90a83bad119c02984a8f860bc1f23ffd33d4ad84896610301cd2e8e80a5ca7e8d3ee63e7dfa459793c9dbaef3569eb4f8a021c6a3d032a9c94d3f6b8278274d0088a98228\nB = -a7cbbb6a434e4b022d312ecd4a45fc7fc4d3aaca038cca0fc56e529fe7119ccdddc8e76d51a2fb862ad3d27a16ec8a51e5f66b9c7fdfbddcd05a0ddea14172339cee340c8c651eb653c6aab6551c99ae94f26116e15dc62f2c2e63305bbf84590fba1327ee721150d46464d7e22d45d53ffd44\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 763912f4b16549e6ccd60eaf7a0a1f64d9c3bc83e4a9b87e209a3959ba3cf609cf47183bc543f08e346b6e12b8bdd5d1c07c603f74b286ad432d58d7001299ec7a4dcdb56ca875dfc7ee5c75bcfe2aaba14959bf3facaebf8df92bc12937cfd4a4865b3dd74b243ff62ba256d110b01b4089730cf48efdc66fe272f9241014e\nA = -4df3899b40d51c83dacb442fb143835bcdb550136921df78800f0515a6cee77fe3236dadd2a0800b79ebdaaf8cf4aba5ebb60cdff3e4b4531ecd0903c1674a4559339123e9f09158080fc53c4c6ae72c961c8da2f357b7c05368157b4956e592c41b25642457651abfecb4fed5d9fc1fc3825b772d\nB = 450eff382e73f2f38bc3a4abecd5f8de478f80a6b99fb6252173c90d7099629afe859442bb1f796855ee9a2940f21d1f9dc44f462edd74b479e1f2926ff6faefeb55adbc6152b5c97967b1dc8c44dfb85b5e02e870d2920b75422c8a427e99e35e2a4be92cb0ddc04cb7f4044f716be97b36f045a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 56ef57d56c6d1b94cf0fcdedd3611a8ee444c2e25522b9ad175587619598da341916b183be03b1e73be300f9969120d8f3a23750cd8c4ffdb87124a2139e8ff2c15d8dc944bc3c3a066aa16dbe6dba4a74925e16acdb2b2e83cd7fd5cedade6a7f7409a509c00dadc182b2860609cc9a375cb8bbdcc350bcb2c0df9b3bff882e\nA = -143caf995b7783b1316b5551978727f06512fe114b419c735b3381ec351275fb7fbd6ca88b848c3e8c9faedebd6d084cb8a231636f68f6803d14bafd90534609d4a4ac0fb953417be7fee4e4cfefa452c5ee5d1e1b97ee75f83cca8691a0efeaa8bcc1f1e0f18c0c5d6c7684c9da6c9495d31a32f40a5\nB = -3025fa05c55826c40089b12741b7d406f748cabf692bb0227519a124653160142633700e3c0676000943556f97551171d231c1a35f7b7d8f96b0366eb74942466ceb4660f09aecb2fb2ac050ef699eb05bd8834a2ba959ac71550b5c026b9093c8cbbb7c5fb9390a7818db682b7c11e58996c9d0add5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 42f363c34c20c443c1ea7a1c54f98c6977b6671164a80308000533b2404a7f280adb1f3b98101cba25249131288f7ac68b0ae2572c7777e7381c1f4d05fd82188c4b1ed5636652e0bfca4d096bbf4189a9358b79f6b6333b99e5c4b7a940c2f7d1413bf9f47a2ef66b620b5e220b2c3dd7267452eb1b9d8d9cfb17bbfcdb6abb\nA = 499d05de867bda3118a8cb82b80ac91fc505e0fbc6c7dac5fb61713cb6e715f56a31ae8af4b400461d7ad1687a2631faecd90d7829f67d1b9e36ed7d55704b3f2aea65eac061172d698384daea710ed92cf1140cd4da427174bebd173c2ff1675b2407a84649b0a318602f33105006fe4d5ed8d0e015b99\nB = 17a426a12a0175bb46bf7a7e727eb5238af383cee6f4d5e2bd82b0d29b9fed35f3d8ec95cfdfcac49bee47b25d3b5f375a3340fa83f8dd9330a593a974d208debb7e567e59dbb7251b54e42dab2cd50fc63aab050a41bd88282373f8195c94c35f61bb48aa921f574cb4ff0984ccedc070efea8c46e5cf8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f03374e9596cb56cbbd89794090ca7a4b437f4c05fa38a09db60e5ca900b208fb85b52f71c29fd35e62c9f9529d7ffe46fcc54607ccb07f6f8e13fdd4ff1185033ba4fcefb1ed4bfc42c3ea9f05276767d8dc9b7b4aea4c8bc0ce84951d1f590cec0751f73667db19060e2bff64da30fc048a1f5700fe3f489920675cc3540a\nA = 1073531f678877ba854fd1e7f857659614c526847ffbe8ed131dc9f2ccf69e1f1e917bb44a7b905f7ff758f61c06dd59ee09567d9f0df2550fcb98b776ed1381ce052988aa08fc5153e31c621c6a51ca61b386e3a9163a5cd69608b3e200476a8ada35d906c41d044bafe71ef5c6f732935f15b53bf36f7ef8\nB = -de3563925474e5408e245184b57f328e265b6cb62eedcaba809d8f257eccc0a457eeb82c451f93af93ce9f36dd1aab386e7c02b356f31c2d170169dbe15e70cf5bb9073b35fe0e7c7fd7faa91c5b2b0740734f12eb741a9d9ac6dcf7cff59f6e16324ea39e1e07dc5b9daea27ac674dfe5d0a5790abaebde9\nM = 8e2ba940fc5165c6c5f", + "7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1aa22f9013bc1cdebbdfecedf710c1bcaa41c696a3d7dfc1c8c601fcfcc1c85c8cc24be7df2cf3c7311b3b17a4ef2dbce545dc467d2a92d371e02a196a9977cb9042b236acf99d8c0d34a1c4dd8792d3497cffbc87c397ccee5d01fc2c89ef051324a7061e423720d0a3821a36739797393bdf7a45b5fc600824a17043312bc\nA = -4fb2e3fde2a0c653104c077cc6459c9234f86cc2d7b317329b68289826d3e2b975f1a69bed1a53418a0dd86e1b2723f4c4c5a29d003161e667c2315ec24a36f8bb5f2eb0a94f261e791bb829db685cd0ec9e1e301dc140ea57cac1da228124ae029e2b8ab1fa3ab99c55a9ca94dc7b767162c0a24af851fbb984\nB = 63702537a07971e399aa9a1a0795db052d6c8185c79107216babe11d6d8d472b61e604cecf9eaa6d44a2fcdd1ef0b6b52226ea0c6902d929b09e16576e6d1a6921765b2134c5d23c69ed61f36ea9a5552e5819350366240693558fac7a9d09ecd3702076c8c758a4bf6843fa843dfd688bef3f73515db31bfc26\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6acb23ea695d4b60cce53079390da3cb3a4bc3a6486c238c421f3bf6c93c027a0475f656c3e5435f0211e90458ae81772aa956ef284093020f7b58ccd9373f3fdd39fdf4adb8dd64590f4a7fc05238ba20017bdad07f5f9a6f076b71554a7741bdd8c98ec68f8fee88396cb1f47c64d6da4c228caa3dfc7a9a1c032a9ba4fedc\nA = -1b2496ef929bc673042996ae80f27c6bbd33fa7c20580240ef8fba985d1a6117d6e746989924e34f281e7d2509175d0773dd999bde16662e88fcef52978d19cc45fbae3997fa580a66171d398f4f0e7605d9f4aa4f728902cb886e6b6dc9f0161e7cf1ebac05a09c5a1bd69a92273280758173fd2c14550ec221275\nB = -28399206ae2820d26a5aa0bddc4903776611d08fc4cb34a22a8bdc2a19e9f8cdab94217f346a8070a4145f989e1dfb49cfd100267635af0e062872cc879c534ff138fca603b5d45a6860ea85b6de37cfca000c81fcda3d14ffe81da919b2a25214209b085bab9cb511889665fc845acbcd038711533da171d8308aa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = c012c4d17ea4c95a360218adfc3363f6d89f5aa524aec70049ef94c2c05e59a66ce01e25588e164bf2412f9517b7740de53d037e71ec3a1d426f05b18b128c41a878da75421e8c8ef3ebd5effd40735c00818eeb1ec63182b44e817403c9f1f6c1a0155334be63a3a15109be6d45ac0d1b1ef5cc99e9b284b00c487d91e5472\nA = 796fba6276fb7129eef2d1572b305f63d7b8c49371cfb3b2c67b141071e66ccdb5e321fa2c1bcf624c77317e2aa135e1137dfa46a34c3ffefa2fa3e316be81f45614d422bf86fe4518c2fdb7e416bec199de033cb5fef7f193a80c0f0e6ee924a12c8f705f5ed3793ab770914924b45cf2578bdd09c701169f0a881e6\nB = 12cf934763127284e642ddc232b1c889cd86617307b6ad72a9fe0d48befd7c5c5370a0062dfbde2add256dc0af850813b22320ceeaeed347eb9319bf22320b2fcadeb51c4bb26a160f7459fc172c27a91d367d5a232d00cf7bb778fba83afb744177bf1ddf45446baa035fcd0065f9b493d92eda37e9138f4fecf3ec55\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3de123bbd50c35805b943e76e97b7e664eb9feb99860750bf97e275029e836217375cc1910c13269ffbd0bd72bb82ca445ccc4b693742a96d19d3dc23f78e5ccbba46d9ff5975f239551c36403ad5fe86997536456c4a5ce54807c24e3b5317b1c7b2a1661aad85b63859d427f0703b460cf72b9acd3f87e2e69d7f8f15e972d\nA = 1d0433d84f1de082d2058475e0168ceb369013a67aa9417f066c29c28272a0b3f8be5ac7190ab78591ae72a1dc8ce628c683281a9ad563e134387b9258b9c96d2df288fc118a8cff068ee49d635343772c2fcc252facdfc93112358414e1734d6948b909b53e46263e9a0cbffa141ef77bc98e7fae8ae2bd85bd875aa7c1\nB = -a31a574d105305e47f4fc00ccea0cdf854556886b524901c22e6f3b59a42915932ab209a8d5da29ab70d1472dd5378d9c79a7447d17665f9d1f1edc1e545e417cb65415cb8a368075c16264f42555d26e83adc704b5c126c6129318a8f394af8bdbb32c8114470d11b2acfe806acdc7b96e1e348a32ff96a988de76d4623\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 770f0c3104c0f3395fabeb75ddfa2c21a111d23438463941239f7c63e4b6e6832b84508ebf3cde1d90cff0a2801beee05cd5118f9a726a987eb58def6780be899b473ea71c697557ff63a4c6db894e9438595acdd98abfb529d75bdf3c1d619d6165a9edb6aaab8ada50b61a3a84de654706a9aedb7321b0523558e8f18116fd\nA = -5fafbd498d610e9f29c38a5c6c262b71672fe9e9c84f0f071b549390353e4fd0101a059b7c547007e27df97761767302458f1936395142ce5776b0959fc5ea039429d64ac5d50c2ae0ee45d60c0c50b7ceb4ff9853d57c6e883f588017ffcaddf5a1aa3e23ab068877a114d9a2cf742f01f5f5d611424c8ec0d082f5c165b1\nB = 552155ef110c126afcb87dd20251220c7a43bd0215ecd22249a21c93583e120ba6f046c6fe03086ef3c97311c4d520110a450470a473d8633e3560d2cb44c25559af07516aff50d6d176e8782c06cd9aadd3354cc695c4ea8dbf85e01dad479c8e8438154351fd5fcc6fc7e9d2162ce2f0179247f756f0b9b34b54be74821c5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2e9ed66317734668c4c354d720a011fc65bb67439b2ac9203dca65a8f567682be40cbad4f55a83e836f1fc135596b624e4327acb085a61b6398237fef5a6e6560b488d4a673b5ae7d734b896d9647d71087621cc81e94d58e01fc2cc2dc775f9ab1b6031840a672fb715b77bd636e3d87b4949ec7bd60721bec8f9907b7c072f\nA = -1a6b046d691830d33eecf2c53953676ed3f6fdd20c2252f6e915052ec28ad1fbf7a5f264acf87ef8ecd515ed921ce6b85017f3d8a8f1d14f269f31e3307c6f935ad468cf012a912b0650a15106fb949cbae7b36c9cd496538bb0646a7a28989dfadc719424519bfa43cd8833d3a748c758f813881d83c98f7cb2a63c2a4d06b8e\nB = -34f87db0f839af6e4c4bf146789db36b3d0bcebb9bad81db690ccc3a35070d8830c9745b2fe730a1f3a252612e7026bf9889169b57b8984a5479cc4cdd6844ee3e150a2e7bf7680eebbef30e0591c895cc8b2ca488d489554f2339e2f55598717ddd8ce444a060cc95cad9eb478491ee8d3b8358c3762a970224abdc1068af0bde\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6455ff7c12bf3bc37120fe3f1302a9916a6ffdae6ee6a37fc23ca2f3a7ad910dc0e1027d4dc304a8eb4eccbcf3c87cf52a13dde472c07e2df2420c1d36bdd5e88c3d76e774ccd2ecaf6a0ef55b8c60231b1348a738f812a4fd9d0c158fd5a9fb19cc7cf9f000860d4cb6509271c8e43ae4193843324db02a029beb58ec2955ad\nA = 54ec203e2ababdb0348135c0679eca2a8e778ed46e53f195331a48d3828e5e40da804ecf95eed819ecefaeb9c5377cc1afb1fb220175990d347981353e7d90637adf8cbb16812af8a3783dd312d967a490f8efe3f23746929cf2a5a8df58e0b878367f6c5e4d3c086f947fc2bf70bfc3a0008a8bb1d7d83f002930640b6ed94c334\nB = 1311b88a05224e15f1465c8da26784dbaeae84f818e029301ea39a982f714c64312f9f02d094c401abb6a89e8537d64c178637364bd261f4a27beeaaa901cc7b3d4e36ebcd9453cda33d47a53c6dd1d121dfb83a222cfd16158eac23482c8abbfaca59e765f6c1fe871d884d281793eb19f6409dd6bbe4083bf762ef24c24f0127613\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 64104f6c06e563ec66de4442d35d88117f2535edf9e012897f44daab5a1b8a8696f84db7a68d64ae24a394debb993bf6734c9df542c7e473b2e497396ce39a064789d5d7b339b65766b002a18096e7fb9f312ea5997c2a85463fbd6fc18f25769ac2a2123ccb0e72f14b0608c4c22add72bda138b83f986e78d5c9da31b15b9d\nA = 145f580c2ebc6c0354ebdfdbb1d3d7fa17f0b55493b0b9a11b71001c840a967dc77f0206c3dde161b5a773a6b5fd9471fa08b205cb6f728e3afba440b55268d6a9542e234ec313d53583c580a391d8da5943f4a900b279ec9d8933f2cfbb260b74ab714a8b9a1af3190d914b6e42212df84f933a237728a5fd5473ce2e272eb82bc83e\nB = -c67f9b9295dd5844307b8fe3cb9c1875257258e4be6229ab097e148c0175ecd0de4d84fe03c8da6e27153c709c2526092b1abc73b5fb40f1d4d", + "a9e0f3d8d2fd5f8a4e6f3c30befd80e189b73fbd77e8547b34010d2aa57072db0f00537cf3ced95eb517b23e0c854b4becce128a575a31037c3a9e106a476d8b0277d26dcee435cebedc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 11913c40d577f70a5346ff1cfdca492ff52b640eaf257510d311872c8df7ba9756973da5b9206c6e5254bcbbb4bcfdad5fc4594e41ee44e77f168e2d20a4b228480a9908b102dafddd039ba7f7619eed7057e8af3a72ee491a61dd049bd947e5b09a94ef94d5f336945f47104fddb8493ef22fb648ff5376b68e96c0555d74ca\nA = -5537630b7cfb8daf76d14e617f7b69f7b75b472801a9a818179d83ef2984d0abc8ea4214ed3d3d2bd785060e9c2819e861d0df760fc1daca8340e8a2c997c9ad201d6d2f12a82ae3883cf9f5c51ff1c25277c28175859a7b8e5b6cdec7cb3875071cbe415bb698b85cb19f617162587516f93c728ba8b2cfc19f238e2cfda115b8ec0431\nB = 597296cb27080f33a24241c1e98fdec32f7a4013a7340d367e4cf2a521cd462a2803109c27fcec353a30dd20053a1f744394fed75829e8396f8de434399bafd6cdb6e0ee81343f0cb99ef3087a7c69bd43bd722745a46cdff0c2c837fd87543c3c63df3896ac101a145b478dc224644996fc72460a89beb5741b91a42f2fbaf0d62c099b32\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 42f420adf5c6b32ce53fe23af4e392517e37013b8c3a7d035a93f6ff45142b0b0bd5525cde85f9b7bd9ce219bd3514617e89ef4d9279cb9a3e89e44f1994d72febd23ffbdb0a4f19cb76448199b31c5cc6d7ec1e46fdb67be1211c0ccd93c123d56ac0d9cd2ad11f0c58c713165003495b75b60665047ef80f6a393474cb727f\nA = -1c6ac9565d1950ae6c55025f76e0a040eed0462218e97aea87208ba879acedf413ffd5e63a92dd8658cf5f49d633ce7b126091a55701168ee4932db004dfe8c35c939887fae3a892b0b04d8eb74191bf8fdcf5566b4d3796a5d2596b1e750f64201057ae60aa705edd58aba4b48f6a2e511bf5007a6c44a27e3efd5bf2708f7046c1fff7864\nB = -244f2a90a57e5d066fe22f4d52f91b44882b8ef76d1dafc3387abcb224eda4a2100239e729bbc745237f8129d457e98eafb2ede2f3afb81e63520493da2a5730f1170b31fcac21259e90c894f8bc488c5e5dab2c2635bc7b1ff56c3685607f6fead73a09f83a7a168c4245729ce5b06e482d7d3d72eff33d14cfe2f32f72175484ffa292a9af6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2239459025b257fd0b6659f54b8874f93f07f4d6240f8ad761c9da288cf1537d8bd001eced284bddf78edd611c7f28f1393c6fb879aab6e7df8eefd347d63628b1ae086148f488b01272f67ca19db71a2b284eb17e17aaf1e3e8f23ea253595de474d5cf47c16aecfae360eab7855868b8af361491f6ad96f893f9d3eb66d07d\nA = 558613de283911aea1ee21d6b926f531f778c5226e978ce329860682b5375fe5e5328ae27b00f504f2a2d24470d16c1edcb8e76b4d1a740e55538e79ac7da4b45c5299993513ec3bba7e7395dc829a00d4e228618dd348fbf838eaf0bd50f6c70253fb1c1c734a07d0813915be25d3163df13511f3675022cb85af7646c14ba5d13f615ded8e5\nB = 1f3c3c468146c29408d9207e15b25186d3b06b3fbf9556eff7ed7ef7788032d87ae1a4d2a0983902d4c70936c615d8c9ee26c89af8b58d60231ede54e859763237d5ac59af686300a3e92f456484ce77700557ddc0f93bb40e5d2e5117f2356ac7ffca26dcafb3ce7a5573e07ee97515b6b082fe75fcc9dccd76b4fd416e69a247fab2b30965d9be\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7650985e7c6e5461268867dfa9782cd8154bd6a4bb5857d6555e9d9746ee79b37e44638940bf8d5e974911327f0e53bbcfda0739056bae2248015c35839f35e7e359e93d3a339e7af38c0cb43eac5b41e1406e34cdd4afd458a5d126f70b5d683415b490e0ad61269ffe7ea8972eda6addd447d97e60891e5099ee920e18f233\nA = 184845d3762ad1a9c925c51fabc7b9e15570a84a06ecef994910845d56869264273d75fbb84a31c97c27eb9779e8b39f6829638a78b266326b60546507f65128caaaf36d4e7f85939b75cfb3145e2b1bd8372531cda579f59efa0da9c95a8efc72faf326d35c660b4444627d328bedf50a919029dd164de051a4c0c924103e365cd640b9637d8244\nB = -977390f52af784b52c1d54e82131b072a1c308406e9b82587102e67c6f7145f0020952231a5f0ce9d130677bb5a7a37d5a06dc570a13a29673c8a9068f06242ac438806c37ec46136e7c1c1487ca2d330fc1f3c1f42ea51ba2805b74c44a61fb2fac109710dc3dae78a07057a753898d4e849b910f035bfd807178f0108812778345b256c7b59f8883\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 35d48c3e43070a10dac0e256afb83b219aacc0036f554bd998b9092ce3bf87bb5d3b00947f2c86fd4e7ab830502d15fb2d4e47ead087f5c779a9ba56e272ea86116e2c81345d379dda6b581e9c8f4df8ea56c78f04d4f7412d245e00ac645847af6ae97d5d2ab27e48cc878d8b510c2dc753f6ceb1b9e7bdd923e0e065a6c11e\nA = -76e575cc79d7f0c313a489b255e85d114f3933383cdfe75cfef649f639921eefb9b3b3184351fd0ad252c6e477e153ee586a0ff6da1e1b2bfd7e953e6dd778c849843fa5cc355b31f5529ca45aec81ba67a1e364d5a74a4656d266f7decdd47b2fc2d81d6c298afa2d1c39b5e8eed519a9997a14513537cdcddde0b5b41314476264d59b7d3f0e9a65\nB = 6b7faa437b4e8db8fba56c62eddb8a81e9090d1b6655a2185d656b2db0e85225992297381d653e707aa15f3017880b0f07abf3dc455cb09c4e551b3df3516c6db4ead79b88339fc33dda96bba76ff7c388363c36b67fd5dd0ee63f92f67549dd77e37e9902ae51cb58057579f03286fc48e3b7fba763fc5844c222e6a1eed9e1634d0bd034cff222bf147\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 445039f359b55eec647296fbff4f22beac09cad32cae79c13d591e314fafc2b77839816aa4f641250938865b0a2c30a10e23da71a6dff5985ebf3df4429fe64c327557b12d987ad9e9971f7c7b1e4ad01c94e1e5322dbcbc4707a959a401624619029558fd6f5b14564469b13146f9a2555916491e4d77caa70f51716b299135\nA = -18ddf976fec2090f7d1f4d41b8f875e56c813c04338f595d6e591b3eabf9e105be792f45354ee9beff997e6c0e8ec3fdc714c07b3466ad1a949b9d30da0115f5484c3b9e00c7cf0c117db57c3c6cd7434371c6d9ac7a5da1a0e2d705bacfc22f62785222d59bb5bcd3e3bf2df8e845953c6ddf1b546cb75b1698dc8e20bc611294ff288056723f1e46ec9\nB = -2cbaff39103570df7d85a5673b50fb8818434bbc19ab4e33bcc8289a4047d85de1b7029a5cda3976ab12e1d891b7efe3d5576bcb3713c597771f93532853290068761bea04200fcaf9b05d8553b960ef5e28064de89d9e5097d12b26af0b64beb40b33ff82a55af7c5838b44282917fd4342e2065942c724f3cca515d9142fb8e46652242e8f0ee5ae07b6cb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6727c0d0ecb4a375d0fd1bc52146da1242099d445ed9e87b1fad4daf8369fbeeec49027d88bd98efb425c1e3f73e412fb327680068ae57d4a53992f3759af0ac1b96a92f56c2cf552e6682d1fa90c3910bbc5c0b1754862ee13c5ebd62d5b98bfe8dbbf9bf53bf9ed0b967f3c9da24d4334b9f3f75314b429b05b8e27142623c\nA = 5cb6c49efc6767cf956885690ef740337aa71b90c1d4b9b0a9e4734de0c0c50f2358fd45aeedaca6e1dd0fb510bf097bf46513ee09f3343bbd1c11f507eb61d51ada40c5d6b730561756480063f60caf05141bec9a769c241d367cb92fa8e229ba2e471fc73f48812a25bfc7553c395ca77b80443ccaa82fbb7198f8c35c3b5a2fff977d8b2a29cf9358ee1\nB = 16ff229a0e67a410555dbd4b687f1470ec854ef67db73a902f2d19953c55071c4a26dc320baa8571586f1fd54fa490b0d87dc83e5bf20b78956084275518b307ce69aa4ca1079e3aa753d97fa1cff62e0b5f3b99d96a24e411fc3a3e375ea21b7b35a578a72df68d28286fd9a324c06930905f696424780083715f77961532bad061f3901ed276a9eb6e81ad4b4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6e9947beae4d934253e481d27e854a59c4047eeee4fdc7df7e174a8f045776109c148ba3721685195b8fb59263def88891c5953b5a0ae85fcdbf02abc76f4d3c0f5d9496327d063ce8b3ba875b4f119dcd8beefb3ac884c2", + "5955af61c35a69d0670c3c349564e5b84f7df4252d6d3b29d9a75f09e9ef79f0fa9f797bf75b8ccb\nA = 188785951a3befcab56128cb6fb9576bee2412e6cdd7dd1bf5643babae83c8011af99aada405e119c3be33653862440005be994bf37d3802cb6c73cc312824c56841004c8e871ffb560e93a1d222c93d63684e90a91394b9c8ba8cac27b414bf818ee0de7217bc2faf099783800485ce2e93612ce39fc7e2f1db708bf9bb032d92b66159073fecdb2e0257058f\nB = -8dddf094f30284c213577ceb7f1b2efb1e4213a548e6aa840f801cd6382fb6d4995908b7827078dc3f46fccdb9e071bb8531ea8971de0ddbb714d678bb71ba9d961e58cdd5f41b8472146ff9b814a5d1d6368bd94812f8d38f235f39aeb2421a57499fe7102c1ab167df7d33b32a6dc7c8eb8f4babdd6b6c929d1ebd9bf4774aa40cefbf136feda7b6e10ba4dbef1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3f4a8d90017dbe8e77205e65fa7a0875a1ace6f3f215c2974e47dbac779804143da3dbce92db391c2614c078997c7d1a15439ffb51a5787f5bbaf98a4dcef576a6317b9b92dd8141a8fadc05d3be7c150630668e620a4e07b4b00519f34e422610a160de112f1ab8adf09a9169ba95b60242c89196ac6e155021dd84b3054511\nA = -65ff4322f8e46e03aa6c1fd10a207a5e51db6991bdca232c0dbc9d73ba77fc485d881868be7b14c25b05bb59b7f5bb6c4b2a7d53f35d2d7af282a0423285c5de656429ab7d3af7d92837e41ca701f527845e98c2bfcb51647512e6abc6675cec2a7d34ce55ea4dcfe9e7a8397d45a7a3e73bdff06e303a8f04ab6285eeb1bb78b1455931cae203078eaae826a6e5\nB = 4d936b603eba3aeec3d3f1f9acff02a0ecc28a8ec64b6bfd9b153b1bbacf4f1e186d3deda8c1c81e759237921cec53251250e3e838f5063c4a1eb6cc93637f35aca10b965533d18b713617a312e74c446d63eccee93cc97e3723ab27357ae9b3cbfcb3e2bfc589a1bd582480e776198df047c3ad85f611ca6fa480c70aeb98af02f57d56dc9659b2a6bee222dc3e0566\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8a7f3cde3230af1f1fc25e0c0e9ebeb69161d3864fa5a03e5d7f8c82d9940ded285df35c008f61cc151b4578e2677b2f2cff3236935de5bb1d113597eee448496fe29bb18343687f6e9f1c783863e949a0954de2993d47a03607423b458bfd18c844ab57e9e2a43930df159ce8564edb5a2a37a06425626502e3ff9363b73c79\nA = -100f2984dc1451fd7b71e5d290e4b7de2d26175a47b9bed524fae02bd5abf96faba06e955107329559bff3805689633a4a57275732bc42183acdc792cbf7b6b24dbdc8921b73c0308d0c0ce5d8aad75f7eb16352e67116e859b323deccfe5d9ffdd1f0265297bc9eede073146a06acc3c330458b07b8fd0bb652c7325cafdcfa165f69cd0de8b145d49ddd576fdde15\nB = -21ac4953e54347a56800d75f6feb6ad660b0442174cf3c5dcbcf6528e2b5da95a614d3a8399da14507df4b8eacaddcddd627b10ec2dc5fb8c43d96a38e6dff37189ba275afb9484df800587f4953e327af71dbd58780bd5885b4cdab15ea0f2864f961bbfa9bba6b2d9448443af87c0cf178990254c1ae6e19003b1621f3240a6e5d0a3be2deb5dd253f5e1f88dbb60b522\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 76f8b44df8d8547f8b3d8537393d2805c699eb37d19bd115bd5539adb6b6a00d004def3b7793d5c71e0ccd2b7e9fb87103c1a5f56a8f18ede1bfe1607a346297166596aa78dc584c7c32832e11b72fb4f2d40ae1591f341919bc0157080ee8febb7fee5461a918d2178fa407c37a8243e24206ce2c19c3addcc2b7c3c1912b6e\nA = 56f4d397530f5c90203df1ec799f82a0096888fd370d543e33b5a2c8042108bb75a86265204c40fa5a9a44965ad2fb41896b134ea56c79699a230f38c0e3fa4e5d346cda70e0253b9993c9da5642f4e645a0d96cb732f8f04c99a83d1f1360a385c6e1a972b89915489245ce58830788ce23b9e62d6b48a7ff9a486614d6979033f7914a0735d201c6f29e512374088db\nB = 10fe818f6af7a95cfefb0ea0726f9a3e0e7c30dc9785b1fdf6e2b810515448386c7efc656479794d389e109ef3efe37fa6124c5a7db3164268da0d98538606c57bd2f7df9482860e81f272a27c727d7d81a66fc1a9bc8c385cf02b7ca6bc7ec2d8d6ba1dc992caa216d02c9bf0fba8ee754af77567c6e275ac1b6b1b36b065760761300d156e40da8445712b8fb206c0df346a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = f580f9d2438b22700c3ebb23d1dc296f3d33deae2d32dea51c7ed3a0ce7b06af11046bc1cc279bb744bc31e7f822c17ffcc5dcbbdabe213bf97bb85c7e19ee71a513bf59b25b3b5787e42e9f3ef6aa1acb8705d69924a107b4f88e0cf9276c2c7c47fa4bf56c4900b557aa5587418f0ddd899630ad3ff678b5b907c07247b2b\nA = 1017a4fdce8bf41ce804b7c9c836d85ff6ee899807e1736bf0357b015b701b9675297e5ebf588ac6c295feed3c6a367987e192be0d89523ac7d64b0b9576f311b5b2705c5398276a52f06085027480c2ca72884ad7be34967bcc6c8cb4ec4fb761e88c16866a2e284b40180eb14536810eeeb180ab701ec47ece62af65a0753f95ca657e7d04ebf3c3a7db02993da9089840\nB = -aeb03379fcd4e87cfd18957a72fce42e016951a72b673a9e81f666b3cb20d2bba81400ecc2b38601bc3270eac46a633a1a6b55c50f00e9d7fc8a20176b93e971cfaa4f41573b17b8ccc498f8a3230825afd0d7f102daee347a9d59cc0914ac8689c1d8b39ccef1f3def44054307a7cb7706535f0cf4007231ba21696424c3d5b42c8e85c278f7c2e8b7d1787effa601ad357eeff\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = be05efeee19cc91e30a9277a6551aaea63aa3861b63f6061efbb0b92296e09f4709529eb849d9f40406fc59c526a4697144cef9661b556040458940ffd6a87ed56cb073d2ee0e6d1f05936fddd1b9a8974a3088577847ddde6bbdfb3d69158d5b3899c13ec78fb5cb6aa7204efe308bbe0b52f18381fe838536707a8a27ba0d\nA = -669660e75eae9930dcbdb99c477c980869417ec9c0e8c4053f0bd8ae62d496daf7539f37af96fd1cfcf3149bc02b8182a46b413e3397b49d4b4d204491440eea65505cf5d33a8e797af08f3da41f5a0804214846bd95d730260c6545d51126278181719ddd396c55f119e84da71f0683eb6db8393b098b3a0c5999862644e073b4918b5c8aff17efe860744d85bc94b582d45c\nB = 6045f903a750b69b709cfd6a1c8ec9fc0d7da9c53a9d26fdb0ce9a17c6a0ed5ba633d6fc01f004f4a48cf247d61f7df609008ca5bdc8eafe06dcfa06bb67efa6a584b5a2f02768718a908978edd475a2d2926af2a6e523549a5cbecedc78323c5c295bc0b8d3e14053078492e82e339ea2c6301412a5dd7efc20da0aad0577a37d853eed820776e672bc6d23dc821b5855eabcceb18\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 705bf20b7d92e68a69019cfd721b27373c7ff22f911066907f556321371fba70dbcb9774d3a26ca43e44ab20c586a3c1546fc3152ce011be66e04a59c6631bc8bde18efb7bf1743b9ed75a7a6c5bf5a4117368b81b112a3cd4e1c44a621f534a11c426451ea5fde880939ee5bb28d9843730e284520a976cd9f60c94751050ec\nA = -17c1dbc1ad1d2d33dfe1af7b4cdc7b69fefec5a92656957e111aac292e44719c7c752ace33dc74a6568be38b576a5ba174bcba77a034af5fe101699c99ca39f8a3b0a20679e6d0180868a232fd8fc775089e185e5eb81585403f32619a2f4d857bb091a824a89de2e84529e5b0702b45771a5816c5a823d81ddc89f8a70cc3d3a0c6bd6d85e9d72b69d2713b61c46161f7f4700bf\nB = -2252b54c602456c5deb86a0f249f3982c3836b70a946f636b22fe00c6e3b91b94e19200a33087fe734ce9a3f92a6099ad03a95ca523b7edb9e1ed3464d38fb96c470464e1c54790cd48769677efc5e1d22f5be4c15288bc5ea1dc184a05fddd5e576b3b4962f37437b4f9709dcec374377db44c8ba1d8611c0c3ec35f9bba213eac59a047e78195ebbbeff941c7f862e8c80eafb72b1e8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7306e3172929c00c29ca1db360eb4ce82066f237e9cf6aae368d1f531620e9b61eb64f5b3e2b735a3b565587d7e955d052df94a20e4aaabe493dba2c18e85fcfb65df166cc48733632d165129b112598bf5e4c58dff662e558e5f71b25f36708d3ab6536b1cbdb5aa2ee56d9e019a9c3629185b188af909831629ffceab634fc\nA = 6b31ef80767a7693e7d0a9ecce54beaf5848120f036923d80b7a0245aa6a46135e32314f3b227268e0bfa1f45b4dce83bea890526c7ac3efdc8e485189ce2c51597c2864c2d3664584be23559c03670622a53edc2c17b3f1a92640078ec35189dd7953e55e4da0290ff1e2996d164d69f1bbe6f5285ae89209d611a7d760e41", + "3e23285066eab8e126c320bb6130a91d67ef26d4dabd\nB = 183f06828033287497322b05ac08f62dcc5fa67b7a10c6c5a319c9a1e642754230c6d9809dcfd2de4bb9e360d6e6e1180f6ec6e0d4c6185e34ed299b6171e653521d0f7b8975ed5e7d2c51d27f9784a4b6f9b5e97379fcdb42e4df981462cd5bb9d0501f93f217d954f6baf70343ec710065eacbd2b778430ddc36a7ef0515f29d5fe78d8708d8ffb6c3391c6f632cb1bacb4ec52972ce0a5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 361ce44d153f4d251952c0b90681a19b7d2d8df7a6c5d459691a80c06107b2e818f93f30f8dad352d2dd87b01530d51fd1c67cede9b1a6167697098e41bdc5dc5e7a3c310116aed0c7b5fd99dfcdb3517c13daaba6ad10879f600eab846cdc110d392d9bdc0e8ab34b317840a725a7a12ceb48c75e8dfeffe2947aa85b2a5158\nA = 1e1f2e44bc7c79a00afc3b2570d5cd27ad5ec9f45aa94f63f2ec3fa6b69077480212a1cbde25ded7ab1c6cb1ec26d5905948e5c1d6d109bd5047b1e038666054606b42e880b609f6f00a219dcfb504d481d6fe709f4362940f6c4b6f2e05d243722cb32bee5508ec94eeebb53b5befa551d3ab5dff9cba3daebdbc97179e56cb778aefdda6a0c24265728ff9e59ca3c2d615398d97e66d\nB = -e018708df037aa2918850fabcad82731487fb812213b1c067d0688462a4d518e5ec7c4c84f2cb2017aa6bc960e2faabbe361ad8f66355366cae869d366f06d7cc32ea08dc51631e7f36a4c775611095d8aed06a0086d0a471749246d7157947a1eb5d5503f207723a7062382b3e45bb84c6f555e48f6d63aaa1c04fe13c0108507c0ced669a5296bcc16debf18e03c32eefd177bbc1dd2f19cd\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3aeb3ff6e797d271fd2271499a740a91569f300d7392a7b5898084012a3c5ad379a57d5169e43089cd58fc7210314758d5368dabca2f0ec5cf6786801bc99b45cd60403c732d9f98936aed76da724bd3e7d4b622dc690778f11fb0310fd4cd980b220627f7a864e107f93a6259081c6581e5dddba4890508af8057c1af29a745\nA = -75e06b47f60edd23148c3736c9c125a617beea7c8fd47e662c9d9be883ae925b7801a0030df3f4bdd3c9fc386f18c4e002e5daf4a6f7fa27b2f71252c83d5f1695e50d62a10b99e1900987b342290decf681a064f789e11bc3fd75d64e2e78ace56e7491fbe0eddd6f9958a5f95775c920ad6c051ebe7750fa76891ab00f42c910550a42bbc1c1e5aea0ae13b7e6f916a5d228bd57e854f7\nB = 434c8e4767d0d7df2125def75a978bb1509a26bf8305cd03df748c6c12b6dc580a2c1ca9a4526eaf3936fbc4ec797d0733217a54ffc9e1d7c6ca04fb39679859d5bd3fa64cd0a09cf1a056094b9c20ddf1f00e134533ba9892c2ca7346ac8d0655250eb45df9f0b7983bbf71102c6f1a2d9497e7a45eea7b3095cac037b7aa755beeea8a6191da268780179a652d94a732a2a5c7b626c0de3145f4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 734a429c91f5b0f06fd47725ded06222c0193dd407e9daf136696f203e153c9bf6df59016849284cef93fbd35edef2cd31c9b956fbe562d2a22100f177254144718ac7d22c99783fd523b642984794bd7beb0d0b363e28d3f3469ee332ee364faaafef25c1d4a11b5e517e44a412ba717a113ea9e1e8f2d6db8fad6f10d06950\nA = -18dcd213e9938fe4b6a64abee3b9867f65e47e5b0365d45a8dee14ddf787f34072ce32f38d4d48ccad236005a23c5fcdc02b72cf27001495663fc56f428072d3f1bf5e33ab2c5f9dd9facf122f7225ea03c2f67321530a642803f65a2e9428f32d0d974e68a25f705e4f8140568f7e4b132942b49f9ff53f04f241feaa29aa353925fcade33a0cc192fee2628c2111da1e652cace9d304d0f1d\nB = -2e5397658a5e6db9d30f09e93e67a30dc84b1e17c25786e041fca48ab710e1d0497ce615264f1abcb23d5aae8412b58430bd801775acdce06cd362438898697940712062b611c92ae6ad10da31784207c5e7b9362b20d7254da0df8caafe0736002dd466d76b1a03e91a8dbe8a71107abd5f07b00fcdca2017391c7c3263881a3d02a89b0e16a2a765a32d24ae6584cf44a88975c539402db9a301dca\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 427609751f28edb62c717bd98ddf999cfcf65128b652be1b5aac0dfe1bc0f7687c580ec70c8290455a9448c69dcb550c0cfdd109af561ece2ec8707c1d02e8097e780f32ddd932e706f81f68711acda0e7610f4dd0fd55f6ac7ca3a3184f655b0b29d2d62974739b43ded96b413b9e3f0033ca1edace24b6bb610bf06b5d940a\nA = 6576c31d48daaf7d6bc3658952c4ba18095f1a0d73726f6fe59381af45a2a6b592adc79fbc3b597e1eea711ab295cd991441fb5fc4ce5f047e571a7d949c709e0d31156184be4b8a6a49691ef93d7d3b120193f6ee82246aeb896b8b7b4c74c27c02cb39fe0335883a3f088a71ab42b947a0cd59dd2155c65a0274ec0836bb8c2fe394500724ef84d869bee40291363389e7012d672b1eab6696b\nB = 1ba2888f30be283b588cddf00eb3ae3c641e35fc0bb3a9fc85d7fac1e81052129f499afd3e8458d4cf893d51fe4a2bcddf70f28c8edef16c7bbfb791daedf1a8248faebe36953560498af652d1f1c7aa0e9a5a667d9c94f7d9525cbd5a82147d58b738dfbba5aa162858c2c66d0dd7d8db38d41a2261e6efc7d0c8b2dd2d6962be0fc796705cec8e87a13092e4a3febdda3d4dbed9d11a1d5f92d7dafcd6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 533d6d8d7384e6e65569ba0daae0a8cffbec1d20e417a6edb42d401a59de0a91a7e6854db081ce33b76faa63f6d866993c245e69ddbe6c86d339f7107a4807856cbca23cee2bf5496388ae8fd8d7c78767d0775acd7bd6202dd75451b424034e2766185969b5663b638d539f718e50a9f752f406c224c000bf1ae1fdd60a2a82\nA = 111940235b144a42a13201a41a3f9e4ff02948f8e9127d9a3007906988a50b36d7622d1221155f2516812074a7888b1d8334a01c02ee33b3164d761d02b36729c299ce2455a462bf18471fca42e5b01615d53723c3fefa5aaf4a039a6caad35c348a0a4dd3f0204f084f35c0b93ab233c4066dc50c5fd3897a769a7c5bf309f7a9c30e905466c8394d509b79d62a69b58c73d8d3f1665ecd9a8a4dd5\nB = -e2633e43c38c0b4b8713c20bf4e2b8ccba680ecfc1139954fc42724277beadea438596942fea1094091671c2060dfccd0351b2fba8cbed35dc963cc18f8e8835052da884799d88ec1887712000a0726b17cbc4302421011d5be8d234440eecc363f09e2c04bc9cded3cbbac9a5bdf0b6d418822fdd90dead20e5bbbb3566ca94ab85f3a00d32842eee6521edd18b9aa6872340b2f47deb961f58bf231e01f9\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 33960d7ceac73f342d46275e04fed56563decf2fa4c0e9307c90288e911ac8782f8e1354fb051a9da8e2db83d7c710b5d2b611495e72ed42259ce783a7e7a8f601c07061ec749481d39a082f29dda1f9c7f444a33ae1c1055d37a677b848af371cd3bd41c851d31a07e144d7add66df39576b8200a8b918201630b3da8e664c3\nA = -402034484e499a8efd610200790d443c5d3be35d19d8808da85954d42dca3f24177de48f55fa2efd7e4f7f624d806a8d461c3bbe0b626fa1f3cad2145746464108b367b13f3537ff395262256bfccce5f0414e1f98b59ed29940171d46ebc4bfa1a27802cc30d9221cfbceeb92abdfa6e84ab4a54965568aa10ea631e82067ae358a1a93a3a3fe3a5ed5636a0c4cb373b4d49f46f8fbbaa665a19200b7\nB = 78ec7dbfa2b28e268619ba6db34a23adab25e7f8690aa9464a7d8fb7c6b87d5dd9d33d4c023bb665f2d96febf2638fc087ed30796fe7517fd58e4120c0d319688e67a32bbeaf62a987a9764be75384bd499b0e00a850f27e303f615031299c631844d10abc571f9f2a0f742cc0e8df2fe3c244bd825bf1d9134b2f1059e2a1b61985ae8daf9bfbd9eb24ba268ca58553891945ff1a314a78fdebb5444677ac081\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3a1ea3fccd6f336e6d444d68af1753b83145131954c20f1e3c433a89eeb7e267425a34d91f67fd65191dce85769ece2fc7ab12d032f3e30f8509095ecc05148e47a85391b21a18257c338a6a3ca9816987abc8143fe443342b34afd8a52fff00dda2e42b1b39322bd38c6a1f711051f791d6cad2a47ebd423a9b933485fd5861\nA = -1869c53f86755aa350115a9f49d6248cedd42a339506b8ff59cb878b7745956f142fc4387322c41f369773ed375b72665026771d4ed1b9ece08f84e4782d4c3b0177853cf9ac3a55f7e52f39c1b82aa42b30628a4fa6a838754ec6ff9809308f675e455bca6f44e298394888d85fee29d8a0c8e9cdb9aa08d68cd70e13a243b5804a3ec199f52ccd462ba6594d856602cf1d5efa509047633923d31f78da3\nB = -2023c544b6cdd8", + "d971bbb345300f7a101f6dd44dede6bfb5f4e6b4eafb7a40728a3063f6d4bdd0f606ddecf062828cf889b2f632d0c9254c28f36dd974aef116b73cabeb2bba98635841c2b4d2aea833e35eb1db9fa9a9d33bf7b51c49a14907dbc6036b027a039192b47406bcc56bccf375fbdf40b82ac4b3c660a43d5a6eb656868d383cebd099d2a73506f675cf29649617fe06097a46de93c13d1e590ef2cc71\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4331f18a94c169cf0253136bc4eb7480c9fa4401c18db1194371dd53e5f7b75f07ec2e1e1c4116a5d2a8b2cded4b22925b67a88af9b8479c6e821d58cec7ed9f780a4c41e729982cb33f69b87d01c11cb9a8f7952db1920b6eb2124fd5d820555a99327117d7e8e26d18e748fea3ebc17e1d07161fda57a21a70c7f4e251612c\nA = 5e7d4ef7d6ace6cb106e38d96085d3f3505983fd952498af3c1d9b2af61e4ba10e14961b339c6e64e11ac758d5fa18c3222138290866970d67d0a4f4e19f453503eb8dfb85b44d1050c86943e7c5d6faf7851bedf7d0cb6b13d2acee25372243591d37dd230907457fb440f83b62395f80f59a2d02b87134887406a78efd77614f3193e517f234434ab3be084f1484d3f2c1f68c67c0d6e863585a8a5ddd0be\nB = 114b6e6726433ea88a2ba965f0881beb3ff4d377526e4e099741f069abfaf29e129a1f5fd243c6599f725a389728f755f9cad767ca1d6ae5c8b3a32102e47af211e86d67574bddfa42b2cb466d968f38b47333b1b55211fd9a315acd5ef62cfd3e83c13ee9d3fa20a06b2292177961dddc7dc39abad9ea31ead1fedd3d699f651b656edceebb0bace11bebd0cfa581dad577b8b42f0a844bcd8c8227880876dd7b0aad1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2468cdb1a26eaee34db3d2724e37f023c8a1788526b3dca99321b574685cc8303c609c85401a58fe6da181daf4111fe8c6d4b7428b1cd301cdb9bf8cb6f33140756c8b490d3b2e538ff294fd6471c4d17b9d9e4adeae0df088cb9daee18e825a368be57af4a096056b9e76b94c8d3b911b6a074ed41082926773a585007752ce\nA = 1e6a59efe0b14fa017c32ffd0962700fa9752242b06ffd0b604b9bfd125114d4e0909534ede704cdf1c9e88a6567f4a2989df752510d087d7b7afb515ad594627ece54b8a8e539074386121c9a3e1c12eb2641ded8719e56d42ef50e2f3b5d7d59f8a6f897174cc00a7449d2b91f33e9df07902a95479731a44fc4ebe8048c449bd515ef6cffed70ae78c832cd43491203a247fcfe0a403862266777947fc2542a\nB = -8a9d3646831dcc852fecc8e2335549e8baa2e2d82fcb90846ee82bcc715c716d4a9f62be29d5e1531db73c2186a4d2f118266de33d966b78f989600d772ffc55b1364117d6750cef67f4bae851e7e3f8fbdae7b79de7eab54cc1fee56e25d0632b2929e352c882ce78fd64dd0a1473e80b6572f0d4eb67f6bd6e45c7617314219d6f7de5e505a9b395096cd36650d23e8d57d6abfa9faaf0ddbff90d32865bf5ddddcaf28\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2909d3aef7a21244efc9b5b16626e260907ac11f3d00647f2170ba37197e47b9767030195c2f6d5eda717a83a152141bffed2e26777417ecd8e27aed8666698c2e85a414dddd52b07b52b0da7e08b3217fa6a331f84820d21086a4424974e1e8cfed3501eb054242a9f8bf0803a94981b7b81776eca6d07cd50c050dddf81d68\nA = -73ecc8a6a1507fb5dad40677dc6ec75f0d130ea704d1e87b00d2bd56a6be21714bb30202739170b8dd3605f0553ff57439051efea2a97def70a6d2cc3fa2b9ec27a00c1338bbd588513f0f320272b8933fdf6635e585d1e79203efb5c95a454fcd7f33aa2aeac08902107e9bfb29587ce8610d50cdb7f2033c5b726742fa9f7f20b4780cf9244e6abf6b812171a64b870c3ca4c9e898d4c15e9f5b0194ae736c3783\nB = 4049ae926bb52e862606842bbcb4a5148bd1063b6a56f331cf10000c524b4aaa80b3bd914cd697ebc98d68bd3c2bd5c87fac4ec68606c264c56e25b19d118dc9f2eca19bebca07269714f2955e107b3fbf85530b1fe99c42d33031958280b8e8abea5a918a41cc7e6980149ad68fbf1c0041798d2046d7f88a395348b295858c61c2f33d8512b6fe75aa8fbad62e2f9b0b7876ef95af8a7b7338a2d6b25ec6355c276fc6ce23\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 22407e4fe280ff5a10eaf46d8e1f5a1e77a07410cba4106466d703b11764c60124fa355733b47327e952a12869476306926cabbd797fc80b4a6dedfbec0b7718ee754d447825cc405a98b85f1e09ebb9294c4a4636aebfc61af4545b921cbe759d3f389beece3f29c2c7c07691a4c46a1a72ce418a239fdec80df48732627866\nA = -1e165ca7e1eabd2ad1264d5ed9c3d2b687f2db5b507a0e4d21d9e042cd46e93c2444c6aea8491b5caba2d8146bac656b7754b7b1ae0f6216029c7167fd3b1c3ba2e20469d386d8566ebbc05cb51bf1f1eb2cad9dc4fa454b07cc1bcdb9b8f5a43e354c4e0f4e62d52798f667080a0e0a15414391269fe8c92f06da74f6209a3b215adafa1eb6866f8b3e419468e2e5b4db0d0ada80514249320cecf034477977bcceb91\nB = -3f314681eaa4cb41a3feae8467f7d76b8b05939731fdfc943235aa4d67bdca30e64de541d17a8971e829bc0159384643672bdffbc93b3eaded7844d824604f46aa58b1f1b9d788106aff53438954af015a0387268266a6ba262e2fe7a4c51b5af6ff7f918674b7407ce8282f66e84fd2582edd809b465e4401c67e5faaa9e5748c06e3bb8ddb23fa649ccaf9657dbf79b937eb8959aae8d5bd9513c1e601c0e536cf60c4fc3802d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 385ba217033463cd9cb882fe30373c2d8e8475dee54aba1ca9713a709f40844905c2544ad792784cc8eafbb412dd68de6f98522dfca1c3de8e3bf4cbd09bee4656c4341153b17c98f9ac09411d16ec9880835cae772bdd8eee51eaba7c02ca6a1034c2c5d2d48e7ae3eb0e22f59bf69537ab6f1e49e58a71c64b8934113eb069\nA = 5137226623f4ce4dc9b80a783777ef4e53ad3c2ec648264db472c517a96383ba1173e52c2659a97ce36341a11e832f4ad293b89696f91a051c35bb1db6182260d4a276d1a9b4be848c206899f87a361d318d38b4073a7470c5743b816cbbc3bc1b20dfd7971b11ad4e20d947e352d42760104a5a3cc590b985ee3b5e98c779e38d2581413a2208d31873f9644ec979602671c9da72fa6f66c603c1bb6d8e690dba8bf4933\nB = 13b45d4105e3f5e8e0ba36c812faeafccea2f1a30e2ce8ffad57ffe0dadeae3a23e813758f270423ecda3da083b42432eead7f04842db8865f9f1e2226a3d298ec1895ae69adc55d1d338c3fb787f0676664564eefe46ca95206e81678cf1a2f173c52d809b1e06641a9b467f191ea09fcdc597271eb43da1a9a856784972ce0eeedd49ad363dee882438f09863ba5af063925871c525c6c0ffdca428054e039e149a424c6d1b5b2b4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7865f718cb30026837ca006f5cd997c5b917726ac6d9bd8c3fb9eabda0854d528d6cfc10e4cd3f93f6848582690c6a83955072daefc6959d33192fcf42a111650e50776ba9ae43d3d26e0ef2c6b60c3871aec33eda8c56353903e7ae96592fbf350b88d2f56e03f7f327022a2aa9b7c484a000135b85bbaba6f8836cbfc81901\nA = 16978c06a03276fa2e0bea45740a98d55fccc9d27321fd0a5b8522298a2a90d391c06c5c59e7eca85efeb9b4c91d4a1e9178adf816d597311f004ef98d209b59a2d4b901fa14c57b7297861ee58b89c9b2e931e4ce5818dd4006f3c40168bb4d3dbbd059c1f1cc24ecdc64d37df16b8e8d0529247c06f905ca88a5d283ca1b9e6856fbe8115a326061905b369791772a47900974339722d19b3aac16a0bedd93e1e4e4289bb8\nB = -de6dad276dcc0a9e271ad523620ec570fe6e3b350b934932ebbe36dd571edcde968b6590be14326e0f6394c0a2172052ff8dbc3ff15d94fb6e36a098286333768a84fd0404dfa354173d01f98484fb20897c439c48952b7f1791209fed94e9e72bfb3df5f368d420d587ae8bf036db6700f77b130459e9de2a541ed885c69c5641defa9436a4f7a69d2848d0e5d1074f77fa688b6dcc4d4c7de25a3b1b040546ef7f418112127cff173b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2d3dfd14e7ec60f842d1db83e29a0f6b052990fe8900887dc44476ed3948870c57e72e91e1941c476baa6aa86f76dd8ab6e6ea41707242c46d39b54215bebdb1f28e59d719fde18bea9994610214ea68ad9f2da24e1ad8a06f8bc698f8e76379ff332a2745af472d52a4b8e57d60280e19f93d5be669e0832824321e9ad8e76b\nA = -5144d5ca834f7bbb35d3fb95818c1f89ebe08efdffd35993a7691c05aa1b67f6a28e219b27fdcb66e516097c9ef5f00e4257c561b1f94c52c577471cfcd7a55314d3b0fa308b59449a36adc884c48ef5f", + "34753bea746bd6fab2f20b86814c9fe50e8abaab742916313a50e3c390c67fda8e3729ee3329dc5e4b7d3107083aa3a07daf7952ebbcfea15fae7338cd0b114e9ab2f81dc2e80f90abff7a7ac59e3aecf76fab87633ec\nB = 48b927a46dbc4e23d714b256084fdc7cb9d4c96a988a71c956e0bf98785ebc9bf22b9d5c6ba0c419e60afbef7b96cc0c4a13e397aa2d2dd7995875d2ccb127169423455d138131199a263151f28d232ff4ae24e316907ace1fedd02a02cb5ff9c831de33e6702010fee2232bbe3c1c193ce792eadcad0c81e7d7c17e49168377b68690bc61f22dfddb17d82a3b993804726037cfac8aabe8548befc52a3c6c6baaec89a392133cd9c45b1b5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3f66970f600a9d09d73fd1ff813e977f539d69fe1784b8a2f99506d868418e4b47338ee0cbceed555f88824f98ffed39befb69e8907a5822ef7cd2a9950a070aec8fe4db9d68e1c0620f9eab4ab529c7e69466e325fe1c6c011bf7ab62bfd1a136597d7d5c47e8eb161ea048477bedc88fa30e4f7ddab2cfeec3fd0bb3fb61a3\nA = -1343c391be3f2b72c4b79d8d6091389c9602e97774b18eabeaae81fc0539336cd8c899341cf75fa758421c7f32eba9df474c934642003408b32db66cfa92e6e414b42b1d49c7e655ffb4c80f5bbff8d2774ee4f7198839680175e1ffec0428939653c6697eb3681d0f92634cab1cabc63f423d5a71d65fc7150aaeea74f9e0153923a1c65dee4a165e6a01a88655fbecd2db7697f4d2b49fca2508e2b8f84129785d36d88bcf59f4e\nB = -225a0a4afdde6f6450f28736c3ef6e67d67ec6206a63b11763bc6e69b03f1494b275ac504868caa6d56d684a12dc1098ab0d030583e73a2f45a42b8607c0f19031b9c5f07fb71919868911806d210d43aaaced5894e844881e89bab85a203af9ec3adb105e50b4250343ca50c26df14c46d73a22c2e4804d26d44ff0bbcc13d0dc7e326c9e4eb441f493c9743ae0eea0de045e05d19ac32d2379196a165e63ba640ca42e4861caa24c29cbfabc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 54e95e86e87bc220c8f53f8485402327885be34e34063a1b81e52a23fc3056758cea1c039ac4e513f70ed9d394f5806fb771dca8e342368184e674e6296b9a705c6380bdaf11550cffc73f9f55b9385c85fb648f105f11138a3e1f9dc0a39a0f9755f8328701484d45784e3e4b2ebddb32c9d9132867c6513201116428b791cf\nA = 5f1239e0b5dbfefaba906bfd9003336489ffdf634333cec2484c582dbc19b66782ba40942d047c3749597ec4d89ef61b7803d33a9842f0c903461be37c679ca213aea894d36c1e12bbcaa1c679599d2adda9bd23e712dd0d0bd3f91d146e7a04f3e7ddec8b0db7e12377ab32ba241ed1e01da070c1f3ec85efd8387a7b9421453969ecba8cbdeeeaae6ddb098084bcd250601af780960c32f0a1ad7d7e61fb19f40dff1060c5f332830\nB = 1113f145de014bb6dd6ca05de159b97e9736c45bd3bbd8477f739daf79615fe329ce948cab9787838d7daf797218af5ba7925685ea341b802690bc9588ba3e916145cd3ae9d0c4a149637b890cf50fdfa8f89a62e508eec68f9332787733aacdd57ec1f359ff7fde76138d5b33d32e64cf7d252f2bcff14be3adb1afd8da9dc930f5261e6d715ac75752b29f083bb1de7b0b89ddba633b8137f3fd299a7f77abf79781a10d897e7bf2c958a097227\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6e0160eaac8e1c31cd3cb6c5fb91ba086d033b4b69e41dfffce7569e61770f6629f23e12f0074c47c46653bbba94701ca798e1a242f7c4e25708d3acb5af6ea307b95cfa220f8879cb4cfff96b843d6eeed2b15c8f1bb21bb2b511cefbad0618d49d9ba33cade6da6ab3b846a6a24e35fb36d41201d3b85be831522b9bf509e0\nA = 14f4e24627c773527ed2243c0d1947395aba5c9cf95ae62a48827ffc1477614ad9c7aaea4b4fdd97e3272d3e220601565aebf87928c301656e9edb08d6e680de845615bb3a81c61ed043adb9d708ec1447f057087211673fa6ad8977166a2b4a8079a4f29d48e7fdd6875ccad05d2c219922b814589996cd9642ea2b798197407acd274da30d3ca008fefb40a25b38cb6042a581393283d6448cc69df9a5dc2b0777052566a8608a1010d7\nB = -b4188ebc5bf3ba31cf7c5e100e79806e92ff6f863c3d68a66aeb3ae8385f596dabe6f627f3812d0f2baea319d93ae00de41ab65e42eae7d396cc8fd0a2dfd35f303117fde4db5e8438df0c2b3b680dca538b42a7c844a9bf0d3697fc89ad0a73594627578dabdc214e0f4aa06b40987aed473e7f42d318bebf7392d9c898b4b8d73a94726aef65807b2ff746d4a9aa76303ed7b4fefbab34f5c87c2df82d20457f68289f7b96dbeab581294974e322c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8dd91f390c1f85f153f332de17e5de82979755d835398cdf3dbda1ee73c68f8e7565a964ae33fd5b1f1060572bb3af67eec79c4c3e2eb4de118d471f74351b80a5dcafc682bc3cfde642e611ac1d5bc2c49b308c30985b1161c4d78cf7621b503e2dfaceed886befc004f3a729b4a9bcbb8f13791d973bf38fb8101d6b7a4d4d\nA = -70e99398673324ee83495aa0aadfffd7bb9c94ee5251fff365124fabc50175d794fa84509f034c2b86d83607789338b0eebdbbf709a129a0ed0afd21c130d94b279c56f1c7c1eacfc6cd13f724a9352b2b37412242a47b23ec61ef0040a8855371aaf238003c45ab9d18a66cc7dab9653b93c323815e5404762d3f964d4654a6995af507bb2db2149eea59acd72af4d034217eaec0be5ba1d23890081a6a234e125572e3bcf68a6ea52d9437\nB = 661d8832671a4974b493e5d71e547cd46b36730f4017e50c5d1a7520fbb75f0314cbc2ac948744dd494d566ba580a2108106b120a797cfeb1fbfdefdab6bd6b2e073f90c77e814cafd0b7f79afeecd59778b1dfee3446fb32139b2311011576674f96f151f896b477c631237995e11e61e715dd8dd38e802af93124c66eee735c472972000cb4788b26752a630ba63b45e8ebbd979f0a4da5b359abd2905f0b7f3a21b1d381cd02ac08e284218ce41c907\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b591d2c57f6a5484b43cd7ca247c48a1b38319e843257331c8807d499c7763de4eefed529e70d4c144e5e843ac00ee8d106d0d82163cfb7afe528a7daad8e7ed105942d1128a67e38d59325cffc0c3dab9185247e0082e3ccca82a900d917c9bd0f892d4b518a752f8e9d38eab2acaf3b3b59f15b0fe4cb9a3dabe6e0191493\nA = -1896f67485a740720e23e1642ef02742ce5f10a92e51af19e112cc99c0fbddb60d7190086c942d293d076b474d056e74ec9f0c42055d745a57ba370c51ab2b761d889b766cec909811e2b2fd11d6916b753ae00622f038a4bc55b813a5d06e6ac136e81689407de721ee852cd21ea989ea7c8cbd00b64614caf0974a62097b2eb865f46fdb0c1a2e4f2d839066b797e51392e5ebd14dd92630c070acb546dc7438631fef01594878643a4cf77f6\nB = -3a8e2f3b8378a2605f5affa21c4fadcc655f2f8357a3427d2cec0118e55fc2bbc25931259e294d91bde8dcbacd39e6cbc125683da7d0dcbbc67d7c5866f08e7c4732cd4384d9366868370ea40a75beb23b81306303da4a3e26ad357c5c743d0a4ae775a472afddf8f21cb4a1a3350bb6aa71037607c334a0c79468668d3e727cf1d0610e49f27780901c68aecf1d145953e45f5b090855be714cb39aba2efb0f7db2786b331dd9bb8843de8c73c95ab13b6b1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f53bdd643b5b22445e2af3667a93de52f8bc7bc151e196c0ab0bf3b4e4dc0e5dae9e507508711a9e3de52e2aeece6aff7fc8a1db65588de3272839390a35a847e29204d3b9b70e10352c88a10c86cd33e067fb530d20a3a5ffe67938c5a7a9218f1164f36a73324adef64da64d5fa5540d29a76a87ce010fb7d73a59b109280\nA = 75e31ab221c08b3bd73bed03f878bf7742f9b36a89bbfa7e90f9b05ec11edeb0140dcff6e9ad1d62cd7af34bb4284b3a52bf1b48a40f744b561d9ece056a9405ab15f508700b14914e4f427ea1df3093497410a0108066e9b259c1a26ea72082b3cf0e3a99ad054804da7bfa0200d93d65354b75e605b47a4e1e17ef851a37c59a95e1b5172801e6ecabf70f1e6e382740998fcfd8a297aaaba7d04b668e3d6eed40358247767323a8393ec359628\nB = 107aca18938a9cb244ad646a37a212859b3dda7518a5827aa2146b47bfb3bd08d772eb7a866e1f674aab7a1c74cfdc2bc6e9ad1a365686213655b2c7b1977855bcd42ccecb804bc01d92bd7d2667069d853f18a0f0661f028955e39f71ee82b9ce6a81dfb2951b33b123e71264e819bba4d0a8c53a1d99964ad9ffb58b7cb5cfcd3e30b1baf5aa5b3cbd20a0df7ec37563e2b32b4cba91bbf3bb6fd1cbfb2fe0f84d720efdf36e9645c7e9ec70442ea5174528bb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n", + "\nModMul = 32d16f7ae2632b5cec2e90c34d191599acd9a1b5f97845595988c1d0d4ceb9acfafbc4aeee9924ce55e109ec88c57610fddc664316e0f9a5e3ed56ea447111c0383ecdf117ab42351b80e72720a4b1d98d4c73f5235507c5b4f7849d5e9b527d054858c0436ac3d2de2704c4bc25de4cc702f5880d5ae34094766938bee555c8\nA = 133a439cf006c753c132a8559ea13c64f598c5f8bd5043b89d04d7ecbf0ec58b225551c8df8dcb341198fb0b487774867e5b68f9058f58b3cc98168fbed0d0ffa86bf74b4fb0d4235976fa86d52b8dc7e82df176d70892954223cc484ae58b6a60459a9a0803ab856ff9699789172b163615e322e193bd758016f634c83cf50403e416ae241d9b1e44add17c2a663771ac88cf8b9dd94622d80d879ae41f0f4e7a1a32a1ab164f981900fc159aa85d82\nB = -fef33e21c07dc26a47d692c3094205bf4efae6af32f1c0f46ee579c1a22746a3663d66f2919f46f973fe558c61264157d531e66bb9ea10b4b49d9f6ad3ad8762a6ea8169a9cfe01d3dd65518c2e6e58e8c88d1b2f42d207399d7326752560cd45d0ff571309301683770793fe3765c1337d14021d39ea6980934c5fefadb93047ef07c807d0ea5625ae0cefd098988d6eb7af993c062ba313e23176e7abdebcc6e566304a5f9e03da05bc1cc58dfbbc898a67a5941\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 20877c7f53fca97f8e484ba31f23dcf51ac0f4fe4c5121eec576e043c6ec5492725f1b9f9ecfa64195f71909500a69fab2e591377cc2120bd5f60d3fb3812f9e80b2f6c787e0081c1439dbea76b819ab44bf6bffe87dffd771a870e4f5502609249c5260f91175fb217a9eece4166540be877d564049389306e0d6b313706297\nA = -534042b0811c9afca04d20d83898e7653f91a73de1e4b516f3228c6d6d9b963c7f8f4c36e05383da90f4edd072a7eda382c47b84b46b4dfa16f269c2d9ad0fc53ed2ce51cd31e4e32d0c1ee21604d3c7eed2deb35cf8df6fe1c0740a1515e4c702a2074ad6c0fcd403603b4a4e2195d19b265958ae854ccb0b41cf22480389a053f71544cf594f6833f3e4d91fd3d9091df0978d04d3922ed72a4fa3579c5fff50eee812dfb2a334148227a0f5739f8ac6\nB = 6935a3444434b0b03d27545721e253e4281884da027246e46ddefb01fa7cf7a9a030581dfe618431a68ef6d79b03b34f3ed598e7c8ac030e2b4cc887dd31664604fb8afe4e71fbc3135d6d3b4e596044d6b615de7184ebf8dae8fd58506286ae4d3b797aea911eb59ada39dac756d0e9eb6a6c767ab77b9348929a00f8e311f639d19ed88c86eb91f0d4cfddd34e98130eb520fcd2b77507c24b6804d3d65d1b21e6f6d55d1f6e92bba0544829687a096be79eaad7d88\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 24823628d4fe9540103ce5f611f8a6ccf18788120280179a40c2636f30a13e5076503e8a4b6b6ffca21da5b0f9f0d85feb2ce10b51292ed069f35289ebf5130972d720d20dfb8e6ee80c3ac598570d38e57ba33dbd75f1b03eab7847d865c3e8e471ccaf302461a6136dd13b8d31c9f163799a3c24c7284b8826608a9543816d\nA = -1d476cc98529efe5b926aba3160b261723b009e9b880bdea04e9b5b03f173040ffafd1627b38be8e00840e85d7acd3abbae2f7a60b305256b920c2b25a8a4373ebbf1a0c69f6e74792cb0d849872500519b6d1c190da30c572e26b44590b7ffdb464a900fc38db013feecf909b43bea549e05f1b7e70d6ad879c613293cf61f0cecdba1a6565eff1bfcdf740bf553ffd5bb7d74f7e9537897184c527b990dea20387bab0dec3e32727786bb14975b23ff09f8\nB = -2b6e12c87ad91a2fa878b9245875209cbfef400e637b557c868ccbd6e94dae65f1ef8caab61f292d739b139e384137a747210c09ee6f3b2ceb6dd212e14525852b8c54215191e116b7097f6729f6426a8bebdff86cdc16effa08d932ab512d7265cc0f57303aa5e6fd2afe0a45180557935c230558d02c3030b38ca88de5fc75c1240d25a22fe32c4e5096aad0078d50989812d7dd0cbb02c736fa563efd32d14109c44297cdb3d4fa3b93a2e15bbb6eb678e93e943979c2\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2c4bc23d0b4b1f79141be9149ee20cc9f1b58ee0a76d5f4205e0862492c18daa20171285d6ff0b600c358be487e78cb5450d151efcff8d53004eece94c5a37f49a15fb2b5f62a79568382cf0a4232407b139e1ec5a9595bee8435b4f138dd72fdc2946b03817e49864812b7b61f179bdd8389791178a95bb6311df0a5c60db2\nA = 5b0a181f07068af6e1e4b715d92c1b8391949a1e3cf0fe0aa49f3333c826f5582615d39ec28b1367804c1ef54f15fb83b3c578ef3ae957fc89ef22a343175df3ef2fd425f724ec1c3363aa000ef624d64c6d678a4cbd90b41cf7d69a7e03dd60c5d3470dbb75228b34d35469847772ff3d74b1a89a2c492c082d3ddb45ba4df6e3f228de6c64913b79679cbbbc36a2924e722c2c640d0c5a0e90ae86b5364dfbfae80df3d75823aa58ac6c1da78e988a11831bf\nB = 19567bbcf615b777b35fa7030db7da18126cd695ca7dda67f5146c97beeb20df24ba0fda4a4f03523a0d9b9f85d9acbdb5793ecf9c1f4ceac81299a1aa34417779175a4bddc0e95ac68309da51e4f115dad6fec33a75d0c5520692a38df64e8d684c9304f9e2e6ac6a66d2e16a03c19a30efcac712aed2b9ee774ea28af4f37c45609464289de3f9be379c733d711875216bc223f2f468a0c9b4a8277bfe49c590ebce2e027102537bddbf2856c3b6e9389c4d1f5390cb0f346\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 36e1e0b44e5afc35d1e19e88e75f030569eb99d326721ced9bd7416ea7367a98305354eeafd204f1f8a652a8442eb0823d2e6644e6320933ac481a3709777381dce8a7c165b23aebf31b2ea2745ce5b352acdf0707234c824da9e1af98bbedf80e940fba00c229539f310838bd625f1fc103f267265ac1243855622c5df72c17\nA = 1dba8bd9d1e6cdc117a5a01b5046353084946fdddf2696f831a942d9db4637a5ee76b84d4ba63156b8cbc72e40559a2fe9b8e2682d8ba1db0cea042bb86f8ed71f6609df52526c42e7494f6114bb62263d36784dd55d396018b8fa47fa49ca6e5c76ebb0b00e6c764e36cb3ec75e3af6a2c14dee01fab78070239638521743d04f184dae79d49a2bf209ddeb4cc72e0c94a93a47c107f5369070ad95ffce034c554fe2a8391e67f817c6cab5b88ae9748072da5c9c\nB = -849602ea3b79b33af2bd3ef9d1250c507d332e759d428902dbee054fdbcdcdc0a357a51d00aaafdacd696a15a64cbbdb7e1fdb347be5ddb1f609a4390a6f29f79ccdb51bd1f0547d0d9a2780517f8753a906428fd236f8ee1b433e57f2810d0ad51846304a5729f53a871d8b0e14355d24d3f092e50de4f044e2b8aa14cd8a51fbb2ff36b0b37defa7be768c56fbd4f5169d9d4698fb9072cbb0a037c219552728587d7c35f27456c02020f5f9374b6c53bcf8eeaa14be51899d3\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 77eb3cb5277ced02b72368e41f04a35796c2c6cc1273f109336fdfa745aba7c755b6ff3833e9b124d9c78584f6bfda1c94273522f020371107870c288592b7c23964320729d2308bac8813586e72078119852e1d7706d8e15c195486b8d94358736869b15d59c037ba4dc8032ceaa31eac3a9e3dc51ee17706a6956cff8537b8\nA = -6a0753edddef8b74f762bf802d7fe9b38638923ee2d81bfdda354d40df4422e6ac43724de1715c4088da2e68b63c10c90b236d7dcab39b9a0ecbce57628f4c2950c79cc88a89daa20d7a8679232c8ce5fa30525c56011570107697222e0eaee6871adced52ba01a3aea0ccc9901cb3a09eb4db2f93aba0083180bb41f3f9eaae00fb458381213dad01997e9b88f21b0a79ada1ec3837ac2b63611455fab6839363b796b105c3be6106ff284544bda2a32352bbce6ef8\nB = 542c5fde65111ec8a38d76d8c5735cee17329dc41cfd0f13bf47e6d0e0093a129f3449db380ee9a70ec1e44640839ff18b950c8fd89346cb4701ef753e6ef49dfd9bd27d9987e572bf8e68df399cf945813582fa1d33e07be938a7729efd9a5e7d730bf61c537770a0727f6bb9ea6add5aac9267bf910eac1b7d92ab4184734ef8b1d184c292b2b4295ec1bfd17b8a2a2e4d315a8b37b8ff9bf6a1e94a4772267195c5a7ea6f0a0c267337fb97a023f1b50ad697ea31451192cebcbb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 660a1f378a23fc3b47f693a347d90640fef43add9729d74546933f4b78a26968cc9a70ad6fe8d85bf28164881bf7a99e8b96683c6f4fb54162c144f99a27e3feb736f0d382d7e5b934cfa835c723191e5692b7672cf6918c4a7a93b24af00b1beaf1b80320b14cf2d1539e3376779872542406a5df961f765e59f3480e1cd40b\nA = -1cd74c052e62ee8156ba5d97f28aada75211979b1c5925ed015ea75f693a04c4dd0a705f6a723ae7b79958884c96fc07f81fca064ce2affc70768923bfbca6049952eea3ae048425b7c6ad1611ed4b8b77f7605629b9d198a77a27f25eff2f82867845cc868edee4ae31afc5d022b2ffbf43c14fa01bef8d7cd9d0e58362a0ff9abbf250e43ea5065512cd707791ea4868e95d8fd2357b3b3aec1a06888ae940751c", + "eab01cf9e49015d42371fac30d48ef5853b6894ca83\nB = -2ac904d3632e25a4d536097d80a157791a6aca6eb10246ea21f4cae07aafe907c6e4c726694e14ce12e376c02d326f4bfc02ed539a5b4615a3cf5c838ffa52124f9b843598a3821cf9f1fe94e7206d6a525fad1ef77e7e77162e8c6d3d860d4f568e8f81153dc47f167860cd52c1ca59b15f1eaac6b9023c8b375bb63b6adf6972af8ca62b39f044378b11c4a969f3939d9fed5cbe18c06749956c7acbf963f640a1e1ceab73fc4c77463ee8d1575d018f49bf0f08161ce4f88aaab5a70\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = cbbeda9c467ca801ec66fce801c6765a20148787dc6becb199a15c58fae8d20c1d391a1d9d57e1c74bb412e1b8f271dc2cc53c3355c83f3e2f00f15eaf0df735160a48e2273fd1bd75533cf94c5175ce67e79fa6c1422996fae36ba288a658a7a5422a59d39dd81ddea50979e933efc02\nA = 7ea551efeccda23622a1a5029e5525f46d5ccb83c28ec9adb7a3e97c2b7d936238c483a4a9bc92fe0e21208d5703611e2795b91fd5019272d255eeb\nB = 19bd92c534f56dc4235dfb7efff6d941112d66acf81b079382c86fb10dc5473bb8adebfa53ea3fe6e4df8412e7807aed029694ca786\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a9cd6a0a89578ea773fbfbf642e05935a995a38bbd54480ea3ecea1751370ef95ff5ad0e3203613f0ef6833237d549676a95b720848c5e9897cda82642a2f373951d5746b559bae2d98ac00fae26e5957c61ac1de95318b1b1aa6d5c64a6ceb6575f1b807060f9e2a241e378e6ebd72ade7d2df18d5353db7737caf52f888\nA = 13c68e450e9e091ae45863f6c1faed25906dcd90a43620b1a40e7a506e7a954256bab0225f3678e7ce6c4ba6e3a83c8f04a3491d9bf097adbd98fa6e78\nB = -ddef76382342178fa6636e62887fce6e19590065c766b047073329ea15fbba96f2cf088fa5a989f6ee3f6a513fbf66f621c6ea6ef2fe8\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a9cd6a0a89578ea772021f58ce74cbdd8c44a09b3937b198adbd8e95e8e35541eca26438351bfdcd8600b4f9b71616e1f16cee707c712d40da9a440681f8c8647bc90ba4c68b08ce4cbca458bebd5110222f06b2ca980a2e9419e71064324e8c36289eff9c67f6d5d011e6db8538a54aeff8c20800b0949fa42c38fbabfa1\nA = -6d7e88715e9854b435876fc9bb2d25218a1451efb73ad9cc5f52b2bee929530e6618a858000b3f24fa5f47b5f461c84eca971e38cda6e1f475f6612ec32f\nB = 49eb76e4614ac7b0ed3f534811a4ea6da5ea24be925ffeaa38bb228fa117ed56ae976b590d6c9d9a7a8546d8a6ebe4bba771d6587ac44f09\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 44f8596fc06afdb72a6e4f876b70b8d5d734589f41089c510b0da60ade642fd79cf8e705f09910912624fa1f646da596c137f124ec1a327beccba62a44f228f3c0977fda2af631e249b2a4de17d170df07bd812c233a96d17e1e93910267682d24c5c485f99aeeddceb658a7db258a2fdf73eb0266d26b92e\nA = -122231b14c249820f0dae625342415f0c6e7f93787b4206b79e9ecaeb09623636730810c7936e17a1eece68edc7c97218efb17c069bc59bdb9681a79c910c4a\nB = -3cdaed858523fd55553ef85d018c1097d7b88f6c30060d1e77b84821ca20b5625723c7d4331ccad1a70371eacc7f7aa11220f83f1bf3595650b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6de7efcfbc1e8d2cb14cbe4465c4ef71f0d1d7e80a1d80d9ac2d0b161d45fc9d915c54e33131591e8daeaa11ce02404c9b8494added1bd83e344ad4de7c04f626315caa56fcc5ca2ddd4e1ff064a2957afeb5d280477bf1f1195c7294d89049024fe821dceb53c7d270a8b4653e2fc0a4d8a3863a854bc3794753a\nA = 47423c4fec1eb6779fd23e3d4070d0a7bf9a946f5610eb469876797a39c58577242daef8c34926f6974089fc595508d9c573d0a275cbeaf37172f10b8c849a493\nB = 18ad789cf09e9ea182eaf43b28b4f2540e533f0fccad325430b73101c00e440bb64b70ce0f2680184aa8caea2f6f6517e9b80285fea8b61887a41e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a906994d3247bf8a00f20e4b349a500159d086aa863772e71a68f91af9d19e4c021843f8bb6eeed1df708d55047dc8faf219e00d559517632dbd1cbf4bda61651b9644481d052903be1970f04bb4ee8faab9adbbf858324e6cf5aa9384ceba655a1a107210a9497552ba8a56d5e0e70b0c757baa71d1613683707357827f0\nA = 122773509ee608cd9ab3ff6763629a18eae41be64bcfb05122e0b3e112db48c64d2a5a515d96a042850c1c848ae5fd5f0ccc57b273d25bd8d68568cb00bb17b1589c\nB = -af398208c01ec9700e332f3e694894c7cc412a73bde8a79e08764ded92f0d58db8056883972c79a0c9e0ce810786cdaa3629baeb9e5c370a5a59d3ba\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 64ef5e7063a1d95226569a27218e35e93d870a19a43fba9889a2ca98ca5c573fa56ebd77f1403b3bcad17c1351803a809c245a97bbe32b45e21768f28c5b11ad542f5e687a17f7811df6c8735e1778e94d9313c19fa32a6703af7ccbd88b489c96632d10eebb580cde3b905f6345a2a2b86a871b4fab36fa4b0dab9a6c1c5096\nA = -7dbdc37a51b601417efdda2516aba15827a40ffc304c523a47c544d5c0bba6c1367a20d8a6268a5c3f723b1b68de57eceabbb00d44185ec4ba7ecdce5d80456f8cfe7e\nB = 641cf85fcb5fbacd6214be4b7b06fda1b80f4683c21c1d08311f6e23a15434b42d30a51912898a1c46b46c00aef7ab7663ecba683897825a4b07d2b7dd7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 370f20360ac844bf4275f78b7fe71ba5db6f0bbabfbac3384c04b256eddaf04725d2d57b31afa48f047aade156c34441b4a41c0b2146790a2e15d13b584021ad55965588c6e55ed3b5cf5c36b780a27c5dfb72678d57528ab17ca2ac696aed3d9abb0ca448d9d5789fe37e632fa9709f3bb924c4ce34244d239a940dcddd9c77\nA = -1a0cc5b07271098a23f01b3c0d47cab8b294794b74a8b162ff3b313fcf85ea81fc99433cdf4450970311e1d5ff81e9ba27eb867073ed250aaa7795e44ba8d4000e879bf31\nB = -308f93984acb78c5dac2426d9bccc2e3ac361143807c7d34c24ef8f8db5e68a904ac8bfed1edf3cc90d21c87ae4d224b8c46fa42eea77797f94aa848160fef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4c8f466d1d9829aaca1a22fb6ca5bdba885606b9264933ac2b4c18e3afc0c406aa71ee7ff490fcaa804f457096e44576ff8096fb1d2b3c68450a8bc36d1a2797ab8b621ddc91d75e7d6ba01d86e959171fa428a5bb1f26766f94a553c94f6dcc2e0af90d7776ed3d9fb67e842e88f7d7342afd86e2f5d159db7304ae4d204a3f\nA = 57e894e37159cf3c161be9c97a946454e43bf09a7ae8e1437570a86c6b06f84005c1463d27d726afd2e25aebb1657eb78957a9a12c8749049d12007a81d766dbe008aad6d83\nB = 16dba5cf077403ff4af47438f5840f65fa4e058c5cab3cb730154ae0fcc982ea097c6d0e75bbd635e97314f33ec7e31f0e41cf285ecfafaf36382b33d5e83cd55\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 29d13ec304f26247a45ab6869720720fe019d6cf370b9e2df9a65828214aeb4f8b17969b8dd54339d08eb99bbc66720ed78ef79033fdce6da33501fa8588af86ec18be4c4ecfe01781f9d1379865100dbbc020b892e77027d1f04f8171ca51fb73129dd9a96568904eb44e19f56f842b223724a9ffe28826803185e4208f0ff0\nA = 135ebb133a0beb909101da896e3aad7e26ea72b23e60802e54cc6c58a07b1205e2ba1fef6eb86c420f011b70e3f725aaf9fd1873b6e1c1cc7005c7c09e55550414875cfe846357\nB = -e8cbf3feb7be7fd12b01d5bd024e47538f434b496613320ad71f48a8972f687992f", + "97e4b69b5842d2d6a4176a5701327c40325e98b27e4c0f8fee5a457d92181e40\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4309b728306535bafa6787dd79e58324b3f86eb5409d772018cce2159f75832b87909a672b8b4b14342b352e76ec5a6dd66737cb0a20b81c5ce222133bfddfea878b132b6f9fd557133973a0b44aa41a01d54ab565d6b9c62da67378a4058255047a95923daf5f0f7adff2a3f06074ab1facd986d7d26cb475ee818199a390b6\nA = -7a63e108bc9790ab687e0fb8a1cbe1e9ff876e7b5eccfbc136ba05fed93412dbc2ffb1ec49518e9fb867429cea1d7f82e2b159b75bd40eb8370e8a54bf0e0ac0ff24aa3662774bae\nB = 51ee025b2ee8abf9dc5ebf1a4600131c00ae4b6bff966dae5c49ab5b9017e6b1abd6434736df6daabb2bde254022783764c94e66743dc752c9040563df7016a1581fe7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b9ddcb9ab858d2229cbfab87d87236e8206cf5e1a042eb5ddde201d56e2695a3d0b2a42bda6a284fbd2a5b2c2b80446ce88c024137780c277ec80bfa6e9d15397cc5bac98e58c9130756ed0fde58d475a033fd94b1fe0ecc6fd91a8b42177abf3f77e87c0847a4244b9fd4980f3b42c7c955836bc994f2babfdf9c5b43315ca\nA = -1f971ee9a7c966d1e82166503681afc280fab255665b850645321f67da8934baba1226e9efb59e0ac4483c8724f63556a213f2224b993e4e082eefff0056f7aa8a3cf5b655e0f72ddd6\nB = -39309313b04bda1103ca6f56514026538b4a29ae258a2a66424abe2c652b959f5c1dc4755ea37ebbfe404839505c2807ebe069c9abb9150205fe35bc286ca12b64ac46133\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 47555924c31f040619681d4a12064790e981db2c7853efa17e4d20f741f33c56d80862caf86bfe0730870b6c0afa9caf66e15047e60256fec29469d1760d5e9b77d79a84fcf7a1dcd0168a59f870f1635eb033e0ae0ac17bdb73da803206d48cfc1da48507cb812bea540daa2393321ccb0d88b57abdbf3a3bb765692a2c2ebe\nA = 754d78d5608fe8c7ed8e26a174fa27833a24c48d23f0e702454b7eb578cb107da537dda11027dd6b41daad329e036794de562d7623bed8d9b0e909cb3fa38d4d21a95c5f4246e0b030a32\nB = 1839baa8b8fb6575832136f1d4632f72f36cdbbdcbd00f197fff3cdb88b851cbd74910ef6d43cfae9d3248e9c85662d7fb596ae45a460feaf308823f06345bc5fae8823230af\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9b2f026b11d0674e9ec060fdb24b45fceade3070db4405b363d53df1219a02a664882819fe602f430636fc0bda935b14c55c8a0bbcc9b6683417e3ffe7f5d58fae229122ac6e42e76899254295dc5a08ed43c79120a5e5e4124b8fa6048ee90836bd2de51bbd2c6b9b53212e913cde871f11bf32f91b3a78575a006da36627f0\nA = 11402b3b1a45d67cde9730062e38aafe1d04fb1f8bb1975f25cd9098813efa2727cb229adf9490267bd437220d9ffa05bb993e45d2f889f140faed3ac3c7b53216455a830d6edceb02e8db92\nB = -d8e011f18bde068badedce8106f6602429fbcac4766334a0101b57fe94603203a4a8975fa499d8a68198aefd9e68f28e68914f920eea1083e37c67d59476bca9819a8bd628b89c\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3a74066e7eebd9b63a1dd28548be60573c95f29816f3b3ceef68a5f6bb797d7eb0b0f4ee612dca794ff82f5d7461d995b9dcc09649e2587639ea017865328bb5deef17b5283691724e8aa331d75c635d5e19ebfd268fe5471714aaca8b48aeb846f241c1675e18d35f029b132f81128f19028b0a471b3f75a530321135e35fbc\nA = -6c5dca3fb7b85573d1c8899868940794e428171e207b5f9f89fce4b7159236c0755e2959d870754e902e9c40dc1fddeeff6364f898ec0dd669283e6d26a612d9af3c3ab04468707bb8a7827756\nB = 5446269bbeb613e69286f1012ff62ea767965533624542f3b5c866cfb569d6193aa603061701992cb4873ea8b766606da1b57d7b37cf52f52bf85b58309387200b0ed36164f30d52e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2a4e727ac67451ca9dcba648050a085196460e4aa4836c5652de863c3e2a76213e0f590de3aee8639304c54a9dcd5f7d5d3592f647e3d07d322708e1e26329f4a31d66c7f2e9d482f22cd9823074dd57d14040a4f00ac2af9677a2c98d58ee1e094b1a8c40092e77eae454638bc3655e77441d4f218c637f95c147776f5bdac1\nA = -19fa688008a12cae228c6ac4982ecbc88da248d7ec785bf2289dc9103bfa3a91eb1e5fd6afe9e0cc035d3312e9ba64028fa6a229db6d0eaf8af43d8c410be7c689c3e557137ebd60d3fa04edb60cf\nB = -3e8c87fba4a41c3a84874c987acee9f560b9f027338b584a775c1fcabb766700f758c4d451077a9427257334a569037b0bd006375f71223add62eca19b1e26b86dde0cc251e48d3b60ef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 52e4a3f6892b425b935c6f9d1396d2034eb0331cbc5241e1d745a9619fa0cf0fc521585cb9d6b1034c5fbbbbecdc81c757f768c7a82f6ca291cf5afc98500c579f82ccf0be233066730f738c205c3c188f94b878c11268871ba42a5d950dc8a399887997cef2b6b68badec1ca641b88d1455e6d97a2841da49df7eeb766b7be6\nA = 67df01e34a26e8239c8edc7ddfccc3850f39864ed237d4dd67588efbeaaed1f884105508f69e20ff6a5cfae1516f6179ae6fb515a66ef0a7d633ba4218c30875287ecd0cfeb5bafafc492619942f97a\nB = 19f5076405b3c81519c0863d0c963d545b2834343e42bb3c779788cbb46d89be3f775b62f4114268a0ca0e6af6c0dd659607d40071dfe7f1ad0df9a5c53b741c04612158de396e9c96f7523\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8ac1d96abd2cbcaa8f7e3267b716f675aebd23694d24c112d202653979636d4d47e27cc36f850355cfc5ca16b78cd1848944f8759fbf6b03fbb7eb347536a9328a5cbb778a6bcd983081374a3f543b1380add14a9468358009ec2baa7ecdf13e7260968eea74083459406e8889936b2fb98c8b9a3597e5f9ca10b76e1dd0337f\nA = 1c9ab23ea37f324544280d176cc02762db7a39935f1ede9695b53a3ee2db49d0485c6a3742a3b5cfb51f3c21711bf89ed05afd0886bbf61cbd57b23439a8a165484ee8e4c0e1c0ca2b6478776aa2897d87\nB = -e30d28dd01655b7a419d939e3e7530258a667420fc759bad585802c63fe5efbb309cb502babdad0afb208aff5ce5830071c5a974604c69ee47f76fd87e2460a5b03a57ef0185881502625886f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5df0700adbd880a5730d8c0637a362a9d42c64503c3b9784046b946c2459a619b5bf804a41c92ed6370bba730c7d39fb2e01558f7ec38511b0449d6e9db8df2cece4ed348782ff1582396ca8b3196474e7e5817f8c197c44d771923b6e286e41e7e23c33fcd8765e06793169999544a310f2e080ffe13640b85f21a18fa11928\nA = -5c01fc52e86f3a344180bac284d2376d1bd693f20a46479c77fa57077df62f83b1e81c94e577d1d6733d276f9cf70555b20e3afcb97534e4e0108a6cce87e9292d78b2d7367ff15fb33d2c3289d2a2913b58\nB = 6bbc39283be06382ea91ad6b1630b38f32385ec90019d2ded7ca6fdaa39defbe22585be0df9c0cf613f6f146c71f901adf525336f6573f7f43e661c44b7097f110d4551e8c75449da8fd39201ca0\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2a01005f1f387c4d8d24a365708e2506b044f86dfc011262d3577f7313a8f51ab943037361bed1858e021f8a46491a5c73284c666eb65cea1392a780219f13d7188721d7d4b975272293a5eef63480f30cc9618aa74bc51f4175246301a46fdbd34a6ec72d5974aa920be5f321a97b8f19c0ec56ba10eaf2e61f2b45f134b304\nA = -108bbd8824e8c16b81dfdd4dfee691e012e578cb9cc80cf050", + "c0ec4cebf71a968732da36552979ffaccce6667e46c29144dab75132cb087681d5549dc5508f3719e129553fdc97f545d7ddb7d3a4fc575ea67c5\nB = -2ad4d4078c47a3c8f5f9b48e10d52d72349ecf0f54abc60bad63bbbf4d8efb185de90e5e1a686859e1c429e30977fca492aedbf084019e9ceb4490aa471776ed2e8a09151b37c5caed9ede66922b7ec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a1b1b2d33cb610f1b398e03f274ef39a583d13af14b79e6766859b9ca748237b481a3cfd5d490a073e82e3c53d3ff5cb6219b2b2f71927f27ab6f567547a22dd35fb5919e1ed2b6dfae4d536d6d44fa6216d94d26b33f52db06c4ecb29702588b73ebce87569639f786df4fcf569bb07d5379bf8b83743327248c2d71b5dec6a\nA = 5bc53b3895cff2bf7bf10e24fbdc43d17d277a982d5d92f17b9b5a2b9ed8b6104229292ef3997591e2e6a116fca21ad5d061ce438f33b7f7110293770f8313077152c7546cd522ef4054147edbe1878072b1043e6\nB = 1599b541c9809779df3ef40971e7a83f21564bd5d6596d51a3d96defa4dff41e83ca6247969a3dd9a746ab72ce21137f2d7ea015ac6b2ffa8a32997e8b821064d35afde3435b23e47cccafa74d5192535b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4fe8897417446c493725521c0ea5b2110f91a1b5ba236cbb6ff3f52b0036a49fc82274ca949ac2b592fa4bcc792114bf2f2a78a2cb44cb22c6fe7e4bee7981604de47f6da2ed1fc6a8eb32cd9b8aaca0f2feec76a2438126ae6f409645d897769a6d340308f82dbc6a98ac059fca6f903c5aecd668fa838b67300c654d4013e3\nA = 1717c6503d069103f10bb4b36427fbdd2371b30793e492e4161fe185b2e27469fef6a25566d6b46f6a7f97446315a22d1f1f662f912b17e71feb2c82411ed7eebb84d4f594deffee14934b75a845d83761f36141ecb7\nB = -8808f540521c20eefaa037fc5da782c891fdfc668b955eaa2e4edb592e027a964b4cfbc94c548d785d92992abe282d90dd137c4d76419926740ce138d567da7350d89f2e56772d8f5bcc9ca8d7076540fab3\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8b9311808bef497d8a5d14f7d851567a196a051610246964917a1f9d4f4449357d2411ba9fd93983f6edd76b8a8e1501146b08b6e1fcdd97b6a41cf637b6ff0cff7a2d6351aa1ded93f8fc1cedc81879eef751bebfbd1559d5d0320595c79e3eb1db0951d7c67c663bc57a672faed9e14c7da6be6b0c6bcab3d4d515e51a0b5d\nA = -511312fce1849c3d177d42088e55d534f9f7096282916e16b041f66ea90e2cccddab5cec0ba8ebf0b047ccce72da349f420cc28ab19bc156c1cccdcf5216f19ea922698127f090e97444751dd58fe7a2c90197a9ab3d35\nB = 6a5cab5e322d5f651f798aebf43a62af772fa2cc379905e72d253c49be8193a07ae6164f21cf08baff906ef800e361e1cdf1604f454483e10c8b2bfdcce77c12b0320dea63f9ac0afbb86115b656d0198aa883f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 665e16ba6cba87c646637a233ae04805a302ef4a10d79c5b65b146cbab8c9ccd491faa32937d0ee955dff7dd0ea3f79fa43c133021c8680490b91d9c1d8a8102ab709ada7508bd59042940b2bd3a4f8c195f781313e45fa8d3abda1f8e13b35811b638b2ab101d1caaa92188d2b75b2b10d596ab159583135b0d4d15fcd3d882\nA = -1375af024e9974cf8170801f4a709b4e5862ab7d18464077727bfc2581e557cada991e9484a1acf80182458158c44871e67e783f7573f214ee4ea1f1821a65068f2bbbed7575f03a4bba36b0fa8cb6dc58c73b100a6c4a6ce\nB = -2d64b6bd987d496a3c121e89f4b0c88b6ebc6e30fa9d47981b52862551f3b7251a3fc376db0f2d6daab6e6fc5ea8fa10b040d0dce334ee91d8cfa6db9648df907b199bb11b2b5c41c67d72b760c404b0451f70fccf\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 49e9709810d9f3fef159e5cb45211453e7a94878dfdece19af839b89c0e43b226d7cfd46859963c7ccc753350e74c2501131474e3b8e0edcda18583b0392ee15f1dedcb7144000fc7fa7eabcbc83d12983d2ade477b4687d75b723c1a98a951d21b2e8ed95735aaec77e00de288d16422fd259c665a08a34331cb99299ac11e2\nA = 4e550ba2fc2a44452f068860ce2a59230738a7a15f5de0aeb4d15bda8c61ee3003568dc5971e48343d402112d7a86860a7f08f5cdc0de21fb1aa064ee5df26fa23839b5ff6adaf64a4a18c07efb3582c2fc9612d2208fe99f8a\nB = 16f31365545772f276d8ac952506bf4033a884edf1ce583a63d8d9f6809e29d9cce3b3d227f839e6c09b459951465ab4570d2d36127c0f677fc0a63975801896f2fd17887ca16ff7f265e2e7adab1516ce56ee1ee9de1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 89ca20a3fa109a65b9449edcc729fe97ed45a9bd69eeb31d4a566ec1787b24cb7a2c25b3f89b36fef1cb3645b17c69ac8ae243cdba35e17f5738b35278478bcc391add0b5ec42db9ec1eeffa63a3ecd2ac0338db57cde9d2eb9ca4bb1df84f1a62245c4e585c4f20f26c98fa1957df34409a99a18bb442ac14f0bd309266a35a\nA = 1fd8a096be30e4435ce8cc604ded337a3d9d2fbc9666d1893c38546c4e155315b536d1bc323c1e7be162bb0fcd58440915b053ca0d0896e99265241f2afd46605a2a7486e1394a07b23f3382cd190e943e596c747b6529b04bdb13\nB = -a3960a51af5ecaaa70146ce55d639005e9b6b9b58592441d5876fa71470ade6d1e2cdde17bb80532551bee0dbbb71a0cb24dc8a129c1f6e28920055d87e9c66be27fc4b425737f36add7d72e39bc83aabee5534637e2e22\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 654d9c55d4a62976670a5ecac3a6165734a65f1edcc1ca81a8c444dbc98c3409ac8c4f6fbb92f122045fef8b7971a276c7dc4eaba21f7be7495394053d4f9bb14b63fc02c8a55ad8fa9bb9aa26aca5c47968ea1b7646ec606f53606d5529ded83639984683b8a020e8ded4b2d9f668ceadeaa8160245b36a819db14e58cf2bf1\nA = -67abdbc70db183b8c25b0664805ada269922556bf15aa80a47d31f215e216673b8d59edfa10a74f3f09d066055c3b9abd5434ce95eba91dd51576adcfbc7e2556df95fd6642a3b7e0486a635ed5699eb7fb285589c887c8659a2b7db\nB = 6ad3e854ea57aafb8980f1e99ab9cda24f183dbbc513e1fc92d4e239077816843f47927bac28e41d3f31c9ef134b72c09dcf14e2e9677a430d43002ae70c577d9958341243030fe58a800a068d6b01fd377e61844f0d434dfd\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 74bb23f7b0cde7924ee52e58bc0680f151e6898cc1bd4a2eaaa05faf218b419a19ebf85b0219f924a26002f9251b83506684af659e5b680e05138432ba227977f38a479ad9d1f3cf68a86ea214645fc4bd1a032f995307e9c9ee432e816fd852655ef20214e24522c17799ef41d1eebc6e097b9792757f7fc43124c609ef9696\nA = -19d3e6fd6de9092cbea55d65154208a0c93ae409c3ee35569cf774b8c8b7b1c9dfdd52e9f408e14ea3153073ed8d92746474e524a903a45a882fe46af92b033f2c41eacdd7e3c1ff661dcc5349ed6bd1aa845eb1762f27593708aa185c7\nB = -3d466d29e8c0008ee6f402551e3d62fe044787bc9f243db9252ea97da9bb75f5be416def97f13cbb008fee77f2eeda672bccce1f36fbcd26e1f1299619535da0a3fa3ffa0c6fee82a494efd7407cc770cf46ed1b8b143f42790a2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 197eaeb8221b431d5fed3d701a175abc146a9fedf8060e8e611a54f8da2fb27d2fee4539ddce1f3481e6a64435f09a2d5012540d6069900a332461471b22192fb87b63221c7822d3f2fcc35cc38feb6b3e49b5b0fceb52b0ccbdb4e1fd7b0f3eef3d582a6ae194c249ebc52f215b568712b3e50bb8e01c64b114955ebac2da48\nA = 7bd216d0acd4ee392258a7341cd56bfb0968492fe75da0c9d935713a6ac883525a4a520b5b7940b05e3f5e0c40372cb11b7ca193e93f0d3883fe5840e66346aff0f38829322bbc1f0a0e63ce5e528ba5b13596ad7ca19d20b2a7c9bea4214\nB = 1ed4805e53630b886cd733e5281f6d2699b3c79da615f4056120165cc63858ed2ddfcfd0af0c5", + "fc54662aad90f26c55dcf70a30d04ce05bdf61028730b900587716e690dc0c6e02419622ab8c115078b92315e7c7a5ffe38c4a404a2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 40f69f2d1660eeb6e1840164817621dc95eb930875333bc3f62a644ca5910c1080505de0d54fc9fb6404a61bb2c03b3981e558abf9e86f2047c3928599b529ef3d91c7ccd13c1d69431fb9ea3f02b001427cf519d9fd8182219ad904f47b3785fa05ed24cb0ceafd537311633a2e26c27e61be92eefb28a49d7f583cb6e072c2\nA = 155fb75044fc54a6ba6c46972e2f97531861b8d6afbc358db456bac33a44bb0545deea2fc83023c08b7be473eb68accf5b65b3c5d6af88bc6d8ce722c80d5d1527e475905226b01ab9d7b5a6557250cf8be935339db330df2dff92f2e88e80da\nB = -8c6016966a2cdea4b2d8625aa367e1d079638870f1b61e6b3c3a1e6281ece41018d2ce93684d1f0088d021107fb595390664c11435c6c0a7b93c2c6895217a89c469a37d3250dfa457b928ba6119b5c9ca5f2d47b36e60e4325bcb4383\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9b9e6e1727326fea099eeb008a36539f3d47e3882b77d6089032b99c6cd36ad79fa75b7c19d1509b3ff022ef781b6a8c16fa6881f9ee2c4e00a4dbc93a49829622f4ce6ba9c55639656102d81167ab8a5e1fcf14d71caa60be732f1fbc71250256520c7c5a4579c3fdafc39356a2bbf2c7ecc526dacc0293c7578424c939ab6e\nA = -54cc11ea9806ef27911ba721f19e2ccb111045711d301863792f0cfac798758f0a29111e3a0f84d294a79721067f50858767abf507cc10ec9ea3eb27a91f06e7f6b7b4be7001b548cb7fb734166bad6739935081bdf6d35d58ef56180d377e5fda\nB = 7263e8b9a6f5387f44c55af64b64160efe97ec8a8159e723ca8977bc17c861e22041ea227c9c9bb467faaacfe352b03cc620eceecabb6db2db108b49c69752bd0cc61a5e998ac2f404ad052a51286ccbcfaa214ea8ec14cd9a2a6db56c3d9\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a18a7498ac9194f600cea3d66615595c27a3efa7ea196ba12a80b5f608f85fa72afc366d23f5ca98452dd190b8f86031a9dc097f94a217b29fa676a6042a3aed2355cc8e767d464a8adb888491c8cb82dbec8f117f57c4a07b41e7e6f6cbd7dc25418603b1d1d865dd2140a649c9d52019ef39dbb6809d1b28b3c1ae64fc6813\nA = -1b663403c73e4a9003467ed12766f16354f79073ce89b66066857d19f3b42791eb360004d23e02874254bc6db54662717739eced153944c4776f334576746c5c4145b21a23caa2b2a137498554c7b749efcaf3393c5457b2bb87ee2ca3bef5f191107\nB = -21d12aad97a5c6e639a2ea0a82b1292aebd418567718014465a22b9ac5c8c927963a2a4530c41d5a7a6c14805e56a7092c8716e4767b54a393d8552c5d3c366b39fb3b8667c60e6075e9293bc938e407c53afdd1174843b76aed187f56bb4be5\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1983576ed73d4d87d8b94cd3f70c149c0273e966176b85fbbbb7b3202e2c843bf1f8f4546ad7a4916ea4c731a22bd337b6177fcd2da8bd301f3af9bdcad800449b57986e7cbcbc7eb313d6512b2894c0cbb6cd753a870860a49d6a682c20b5e883b8c4839b3321aede51bfc42bca163a924191feaf05e196d8dcb7fdd9941a60\nA = 576759af0f02406e8dafa330babe9473d9d970bf371ceab30d2f98f4470f669e042e1708e2677d52cb9f99deb9b53f30727d16c389bb63e71e923475314b615762c7612269b5ad7bcb5108068bb5159cb8dbb8d08de2bd4fa4d9db6cf6e3f5997b9b416\nB = 1a4e34794747cf4aa626e964b839ac497b1357090ff63088f9fd4399312df894e41b395d17b8ca1806baec6115b1476912ca9c4309f00a46d5f7a52c8f640075422af06d6d6d796359132f4955072ce90e61b40c992a155b2bc31c262e753aa7d00\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3448648ff9f7425937b6faa54551ce14dd15566e5d41b2bdb1a8db62037459235a5b9546d289cc2295b0ed584fab2e1a798bc25a0c114238f61ad3381a5b441cb67f92cbf66007c980db3351adb9cfd2cfc769b5b9b0bd1701425ce1ee8d4b9f438ce1207fa850aaa1d3d1f970aef874c2b2499a150d29c2ceb7bac375009b77\nA = 1fb54cec882c274b98913e76342a9b8e631bf1d381fd8a4f7e0eaef475642ab3f5da70ca2e38741bd0182a959e5e985f1e0e7d737beb8c725c9b5ea22f7ec25b6e564809601e8405a5b1362e7792791f55ab64a57c03a99a8518d7f65feb0e21be619a6a95\nB = -8180d172d3afe00e0423245f47591d5f750f20d2cedd8ba6ab6f9aa24f74498a96c9001a0124c4f98dbd402b63e71eaa3a7af8b0d2fa417fb1d45f64e10030232b9155169153496aa202745a432e547002954eedda7cc9c1ca76811bd902b192f1a1d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ae0fd585408a99643271eef575285a6261a4c4a92c1956b1ab436d3cacc8d4cffc07044e57b357ffa43bfa9aaea57824319579c5c3e2fe4dd48bc818178beb5fc1ed60afa08828657d00bb88894c975378b1dfb452a5b88fc3c1d81099644a998a47a497c8a2b12c444fd2a088f47576b7f4fa40f34a208fbc3348ce33e59150\nA = -7dc7dfb753c0bc3ab4d07d5aa78664a7f57d64be4d4780ea81e3efc967fbf1bd1390248bbe259da32108ad96bd8b39f2c9f118bfdc96bd06147f812af831288bb687e4e1742dcd1dbf2b7adc41afa28d07dfb8df8bb2da5359e66330f5c65964096a96b31dd8\nB = 756f3e407a3ae698f103fa37759e90554f38378a9b8eb38581e0970ec8f9c00f8392612c61aca5fd37d1063b78c19e3109f35c0684ce523c634190b3164ef06959cc42e2b77e1bb2fd50eb59c3dccdb6090beb809ecb0ca30457a5c5948328eb218e219d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a2aa4550e855623a8ed488bb63db8fa4ac374c1ae953781aac590f78a364fc33380ca2806445fca5bb9ca2fc7ec4db5819dcd5769e3b746286c49a7c80149e7fe276d095929e2cac6ae57e8102f7d4c96261ca44cb6f1601f429528495b6c3169e15f9babc5be696074d45559d5abdac42393094c450d6a4a45bbf60ed7847da\nA = -16d0aea9c752b2e6e4e13f7ab1f0a2c1776874967b0dfeeef7e00f8d9edd1e11d2aa702be45fffc284c47811c51dcee184a134b8f6d1874026eb51e2ec80c94837af4602cac3efde556ebfff578fcc56c00de99a43638ab68387ec087ee269ca64233eb5b1762ae\nB = -3c6b60b0ce4b13a5d6d9ccd67c76ec6b71b94ea7205e408eea099c7ced2f3a462954741d353d0af850b10ffede8ce0bf80b6893288413674504829793d7ae0cba53b163e3f26cd99beb0a9ad540f6d2cd5097beac604b1694a9a2f4c48b28338f9d6a63e75b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a1a8fcb68c53846b3edae33ec070ef5cdcc1346ab3a98a116344e6d2810e2e3f60f0fe435fe7ff257c7ef4c122b3c34c776f4912a9621b6949308e2cfe2e0827536c7464371ce804bd7cac1d76c5bf8b4a6fd4ed56b65434c3fcf0ac7be543fe2d09ac01c564d7b9b463740dcdfa9068d4d8e33f29297ab452e6ec55c263de\nA = 7c4878334ccd9e20cb11a643b206626ea5d0b20973f18535cd8f0fc2f0325a67d3558e4cc9cceed0d88c6d2215c220b8d0ce230fd701502b02081e3f6548e58e02bc2e79e4991f8ef188a84b0a367758b4e534b72cd87de7f82a26de14fafd162a50b359574812cda\nB = 117d8b1d2a3e2049e6edbb9494c68a97145ac3e658aeaa05e8ecec4b090d5f467cde34e05fa7f5fbfa32f1d9dad70955f22130c358468eb371555fdf57a40e1df398c166a22a9df2e1f4e18590b00856b4f880f6629f1a4296056dc66a29b6f0f25490c6a8209b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2cd3de06953acb87b773b8bb28172b24adb283d6adada676f5f4548990827635c51506c85670767828dc5b4b91b45a7ab89a700d70bdba4e0355da32b52c173305767721d18dd2cb6c55f890611e7abc854277a453c7500efc4cd4fb8e6c9bb7a73fe5c77045e715fd35d415b3496f7463ec902cbdc18f9f6f67c33fd78c3210\nA = 1a20ad042f46330df937b879c72ef00dcf39fb85b59186b8e7a9d40723288677ff6ab", + "2b9bce95f34f2de37887c8a9cdcaf231254bd00c7e25b6042695d7dfc05a11765120d1dbce29dc74f35aa1492ba0c5ee65114d9a246b57dcc2eb2ea4a310be98383fb934121db20\nB = -f8ec67323cff9d53499ceb3afd44b28f0538c39dae8c965ea27d645b430c2f8a4965eadc8ed864f2549eb636ec558419be71f986f4c5783d0dd5253738b876d9034735bd13b18fc670438387f84848308d9357ec2aa4f6a453bdd36ff08d54a6800bb41df416b17d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1aebe2bc35eb2e449bda63513b1bfb55988cc8e6ec8b3c8fed5ce4dcf53b95f1b438c41e3b2348412b35e1f734edba30273935b03d16efaede429960442a01849c352349e23b4af88de4d01e9ddb53ae900418d49a84b7fadd2669261a574557c4fbd782f8e8f400895f6a6c9679b72983ce01bcfdb641f5067c94694e9eb80\nA = -5f97994c39265b5389526e3847876a10aa3699e3c3762a127d1a9f892180cce68ca6139a6f71b235da26c287bd3e1aaa1436746d983c23c3105c33ed2e06baa1e880f1744d81a80b98ee1f16220940d721a92118a9b949d4da7d1477db8f5b357b3ceb7df34eb5f62078cf\nB = 4bb4f8f4f4c8e63238e8774ed61a7eeafb3fe9a6e19cffa648defe82f4846e3378c892d223957564fcce79596151658a726031a6921cdca0adf0f5325d858c048a6b94312ebfd19b803eefcb93bbfaaddef120ec3b8c366b6d978524d5c74218da77e4c3b5ebbc66cf8\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5d64678a32c163874d1c81824d628a1051bce3b55c37055acc47a8630d3fee648df5d319e50b4c56f465bbf696433409b89c07e442425d3018a059ec757d77b3a40d516ca3148010036b003721ec9c999665915a3c442d95ec3c01c232feb201be08c88fa3c6b0769e3da30f1d73b66f98e31f4306bf4e23de78e74743b224ab\nA = -178d81e419f0473c426e24428caf25d61b648bbf963f7fb753ae15e5ea3706b53b00bfc8fe917ac9fd6c7096518584566ff71e6d35197f9aa25107a235678cf9ff8ae1501c1d5a15d2a27d39d066e169745e1e8c808209bcede0d732423d0c9cfbea322ba3201ebefc5315c0d\nB = -27ed464895b65d9518923fde5caaac0c72aad0d1b38fcb7827d6ad4e0c8dc09e119b8b98183f0ef8d5d1133f3f108e951caee035bed0d48bbeee6d1ddbff5864bc192b84eb8a500cefd223972ed51c7f720d1736646825f95f2f10ce6ad47a267bdd8c80f65d644df158d7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 52dfb6bcbbc5cff46942d76ba45301cbff76e9b894703a6a7fd1af29d615336372d147c3932589affe5c6533f28d3e6a57ce2d3cd7448bbd81e09a13266ea31630cf044f654b87ec3fa3294eb65873964110fd42d86e78d128bead5f117cac98145051552cc3a86c193d738b973f866d068a8994a49df3fc7c7314fbd9805e80\nA = 797c67ebdc083f3c8b3ddf9847b7f3c2a39e35ce2119f746ec87fd5d86671d8fcf2b4f6d440c43e93f45019032e629879799eb58adea729d43d2e40ede6485143bd35979609a12faae7e4393879c40c0511c886c66a24454e4f9912bea944eaa417c9942f09ddfb227feb14e4b4\nB = 1a599d1cd0ab3614f50b71b93c999942bd3d4cbfe7900122d5083151c71d9e0c299bd927095c5c3291418424a7c12947389bd4e0a3c2fdf67b3f512094ec0ce5b52695e527de2b3804dca2edaeb1ea4b487911053272ea926cf2fb3386dc4b1dc268b808bbcf4eaedd21168ca\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 99bb9082e4537426c61f3b813f8c97675c44ba9ca418960ca6e2464cf61ad4eabb01ba00798463567ed3d829d3f14201c740f19fca623b1e9b57b534a65df0f070a2130489afae89b91003cee432fab11426c4d13b7721e6f9db1bbaf0adc0064b33e4b9f4b795511a0744b52f93e3db7bc9c0a991e4e122c463ff344fe14cba\nA = 187a8144a0045a92dcad94f0bae7285309ec8fac7dc864b08914e5a4dc3b1a6bb9212161a18c22682ace16a4bf3c03dbaef088b09844902a3255fd6adc0b7c6397dda86d6ab67204d8061c36ca20fd4bb348202037b249f6c110c31580148db46dc5b1bfffa38a683a27054c35326b\nB = -e93ff16817b725016279a32dac247961ae9bb00af890fb49c4fd8cf5e815cf98b58cfa1e3735095e6034c9a2f2b5d8030ab30e2271abb45b347d755cd9ab5ab5ce37950380cb306bbec42b6b8056793a0955bcaeb23e2d6a9548684030566eca2d34c458f224c8e337cb8e3c252\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 631f53d02c031f592b3dfaeed106160488c08e0672083ff195b22a2c0b006f11165a245acad6f35dfb15a871a9a2b45c544111f71f86c920b42fdb6551e56c55199e6173c00e27c9f47256349a80236bcfd3acd1730f823031ff9ef594725cb9429ea183a7fb2e03124ebdd98d435313e43819d995c4fe81fdd4ba718aeade94\nA = -72e20f1aa2b5f2c4218fb9e11ced3f45a218f4c83a2017d97d0cfbbf227c9082cd43f939c8909e52c8795cfaa75d80392d3649dd85ddc35bf1cc54ba389bed9e9dcf867da1c05eda080274beb6b868b54fc85e12ae127dcbfffeb043f9d59333d0ab3374c24971e1bc7269450b418c8b\nB = 61cb021a3a957703d14061c21d3b0fc19598e19a17df9d6f2418c76d4d37b3f62bd4037aeeb1eda37f83df44c440f5e49924cc72ec5b153856c6b621350ec89d98859d9d1ec7ac4f0c418c6599674322e7d618c5ca588d5a873d5af356d4771c6cd375f5dbbbc69f50b982b8c4d1ec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4654a62d9491f28599a976288cd2068d8e3228da12f645413a92f482efc66d1737495cd4a4c733f147eb5414a2ef6266a116ce264491a3463c9df1b030d83b315f76f3bef8cbccb5c538478a65092547b91e991e6be91ce4549c3a6e34aa7b466e63eb3b88054f6714083695c616a078ed54e1ae46e00f3593af845fcd0ff51a\nA = -1a342c154aad619e567fd32e7053aef8d98335a4fa0e35bf06acd7998c43d821de1076dc1fb67dfa1156d7ff30203ec736384a9aa7f5f08cfb302eb3a2a7179b2664094c2cc0df73fa05bf2af24a62b8e394fc76014dd83b434df26f8a67a624884a0b9b4f08f33e9828ae64f5d0c8cdc2b\nB = -2c57e15889c3dc9c94361c17585d506933a72fa954ce44dda9f5e33408552ebf49cae87bd0be35197f887fc6c7deca1452a4345eb67d19bd2e7d3dcf651667a8900388e4d5ec71e9433e3b01d2b3d91bb94d0fc3c51c70793f978e4b5ef93a9c6356c0b2f7accb9e4eb457a2174b50dc6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6124d9ce4de2880ae3811836235d6d89a1a4b710f1d5a517153ed7729dfb5b56b0ac10a4bbc811db9b26465f03cda355701f9f28c5257fe288743cc0789cc54a8661f46e36eec357580b00a84f1d4c8e3d689bbc18242f1cac30a87cb7a47ea06f80d7c5633cde4c8cd8a1a7e27acdc3a2aacd608cce9e2efe7864d41a56ceb8\nA = 7b48a9663d914e0225d7275e965d866ee6649d7267474d5336d28d54027ffe8572f4aa26230dc7abe9957d211e6c2c8f3185cae962b878cfdfaaf6cfe32058c299247f372ae170a1f7cf71380787f6e90995da9ca5a4be8ab1ddfa8e6e5dc65b6f168b9b8e29e0257e0eec853a6e1911b1afa\nB = 1fc4dc77f4a18d4406a4ba536e500aff68d133c6e7725717ae6537b527c6f40f93202a2292522fe7d04e0ef804d1a7013b04cd3d88462fba31534770b56d2e5672e8a6ec7a723186024c40b4717defd1433b9967bd692ef81d5d4e39ba10a3223d250ab6e71d5d253dd0a732ed386ad57e54\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6443de73e1c826c90aa36fd7ec5d0c3324c42058b1c35d3adeda1685470d363732d23cceb08c3f973034c24fe65506bd33dc45d7d617a53048dcc103d3d1b4fd0534586c2fb7489ff5ffb98303bb068fc14b1bb6bb43f763dca2c891095e613bb7b6920163aa6cbce8cd93d9d39f4512b6e0b28d361ae11cf76037eab4cbc819\nA = 13f739846ed2c3aa0a1923168cbb46f4f0a2f3942ba57bfa5c426cb4d4b3d80d9530405a31bda329a1814c560d54defa3e03fc4f808606a598607783d539dbb1338d5bc0c2e272a7ff6ee6f93e1665d6f5a0ade30308fa047db086646c763106cb875e014e2c18ff8837e4d4d86861b85a5b7197\nB = -ba019333046f76325fa9f258006a7c10d27e89f6d482b95c79296c07a65b8e3bff4a9c9fa7e5d0038da129390ac851f8c0651dcf655a3d4164a731cd20a701895c12a906c732906038a8e459aaeb293fda21346964a6d53fa3e370ebf43c7ec8f66229405095", + "c6a509d0fa15dcf45de8d0e901\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = d3a6fdf4a26993edd175de9a0f012e1eb15a5a1c4dd2741dfc6d0f9177cd5645508b8ab09c7fb34066ba893c38144c7f2ecadfc2b0d15728b407e5db4fcbbaf1871580426400433f14dceac43d28f03376e791b7ad01a112981f29ff4b66102305f0ecc4fd134c2cdc79a5e9d9f085bfcb7e6c187980e68b6c7639c12e8d200\nA = -464cb16fdd395e32fdc613c63ab4768f8cf72a5b74a0a5b0cc581ee4aad1972cd97db7966d3124e30c9a1c80d85c46da2d36eecd7c3bba5866f9eab4d0fa55b2d440a311654466432c681372a80a7896c9163c12314ac51f652aad68fd9012dc63fae6c7673c5da8faafcfa1b4ed5550f2baede5cc\nB = 40389ba4d2f5fc152308c9e8a8c36258c770fb2d03e6189b96c4f8dee97ccbe426cc14595c8482e9e22486b61fc570f0e7aeddad2f4e3a480d4b75d14294a3b912928da5692043bd98ab88ece87a9bbd973ec82f990c0ae6091245318c2810187d69c38fa80e835300ed06c0723fe475f3fb22de6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a0f9eff3a210912828fd7b5f2d72479cc9ccdcfd3e8d21739e301de02dd5c257c7ce4bee2def06c9d0c90d5a86bc45fa9f31e456d353775916b3d5684759e4500f99ca1f91f6767a5e2f4b735ae4b756d56c358a06447fa2c2ccf0ce667be4ed143e9e1dc627a561d92ae53a62477270a7944482cbf671138bd2a85fce92b08\nA = -1da555639228fc6ead68049d836d60a4927ee77472fa0ffd3c787d55b6067012560f5b1c2ef8bbf6119345dc6419444c675c1c9cd50602a93ba3718a5b3e1a30bc108d796998b24474cdad19bc2960b295fee97e03f2ca7589a3daf35bd28eb37a67b5d2cb35a30998d5f8622bd7e6b7d3fddd1ae9670\nB = -291fea1ae6dd1c66c62ae3a3d22904f4b4adb2a48cb795d50074095345d661a033f67b20c5d7231236dab871892deaa9458c235c342bc81457cca3f014a75f5124ff4da005dcc1108e75527528e5cc9c051a97fc6cd202bb9166f9e72e366bdd77c965a70592e5684fcaaf2e03421a2025ca190fe158\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 50f4d25875150bab63e4162265a632109d6b4743f9d6b55306858034732a4895ffb3720286acceff287c38320ee9945dcd0a1bbe5ae1456b7f36337cb7d22b679a6821a450765471257d52b6ab7d59a763e75e9e64581a93aa54761f6a760866d6baf186cdf4ad2b1a6af26a3e76cdc261d1f07b0a7122c8ffdef595812e7208\nA = 78a1609a7f08c93c9bf9090ca7c93459aef815719b5dde5f217567a9f68ceca05594f6ab17a4666ce1c0c4434e0f4f38ca1f33e501d6958a10da47211cc011da219d4373d2bec4b7c6477b1ab3b00b6c45279212db39bcc11d1e7ba49916c4271adca7eea531adad509ae119348f374ef1203c5af8bc019\nB = 152b46095d3f8db5e6e1a9e3f35c085da00e52764b261c3aa775ecfcd38572d2e86bab2f4bf29c2de4fd2fb6f35f66e8685714634e1be980773526bdbf9c43b1335c5d59f4dffe1a1fe2495ff9b7a3fae3e53e7c3208968e1ad1dd1dc8cf2e2415cc76dfe5df9e2e1eb63f7c7687d539706502d56247728\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5a3ad8d6f1b0763b77f5d40169ff0013de638b459e401f50f4cfb505565c8a4465e28ca1bf988071701dbf52ac456e01e170788ebd2b7cccb50dbfe1a65a89a8aee18b3c11986c9d6e6571f964f376f322e10a1ddd9310bbb40f14b0680385c40975aba43153970237c535c6b0e2cbf6bec918a8fa26cb2f69e98d77215c23a6\nA = 1d5c14b0b51cf31e9d97b7c49cd26097d40454978663f8a74095fcbf9c63e533708befb1a467f94cf599a41220ce13493a273fc30c49275412c5205db712d5e1832b39e65c150c3a4b251e2aab853e4ecb4f00ee5ce6982ef9215775a33565bde3ddbd932665aae506941d3ee31b3f9e4ffc0651f1fb4a5c6d\nB = -93cae5dd84584a2a3d88028d6d4cec4146cc5e350b4d92c52ba2393ab69fc1dba96e244f98e2f93f31230904169641aff30dfbdd3dc5fb1f3489d63aae1efd29335345a79ded546e42f2ee4a70ed932699fad17a771ba65fe6e689664bdd1135219aaa905c962d39531eba3e82c3425c24041e17858cbbcf2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 61211c706730a1b98c628b3c8cb070a42e2ccf9fc6302bb1c2960fb165087f210e9d93416ad9fa21634a05dd0723cc23b8d2a846ab7c3bc402999138433725e737102094db5792249b4b5b1514a416b80c804ecfb04653c5ab18b0a34d8777f6c2955ac66fef62c9ec2819f0e3c075920f951f86b32e02bc43239d9218580067\nA = -46c8c68f492d8f7ac7834f89bc76098146432c59b3301d4eb70d9861a6e24c7c9073f910108c7b35538a79de10640291b54e5755359baf47482b97af56475211573576e9412ee017dcf961a090a6ffb5cd995992ab68e3fe60b6186f7595bd9b8acf8695c4f7359cb2ac709f032fb993d16a74822b4935536453\nB = 46953f424d988fd20700ea08880e7e09ac22d60cfc294bd4aefe637408a3cacfcd0ea6822a679b68b665d6bebed3506d25edc83cc7154b83e22953f9d91157cebd219cd5177fede28c63a15710d0f92bd9e542a7586855bbe57a94c520408fc920b3f8d65b194af2b2a580c90db1cdb27ec26ba929de4573c6eb\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 50a063fff02f2cdc68edccc23976f4b3db99641073c85709626292b9475b9a988fb8509a6223f0a517dbae0cf7cd39dcf1e8ae75196d9f5008c661d8b5153cbdb9520c71068e4719820bffda4c393032edabacf99339e0cbafddb6042ef887b8c498e87e16b62417934015172e63e7457242b864a47aa10e203f47320f03c0e5\nA = -1740e8be7b4775725516d37ba643fc64203f3a61e6b0164d112af56666ad97afb0059c2c4981fa81d72264f8669db4e50e11865907655b1f669c88f5935cacf1b12c1db63cc84507af12cf0210f990994055d04d93f148f213e3d4fdcfe9dc42117c059897697914e3e3fa8fdbf0eebbbb9c3b9fdaa7efa0c9d5c93\nB = -226308f8fbb35b5f9d129c0f6a2bd3e5c272a408bf32020905acc6d02d7e506191e76a3a2ac47cf7a63e6306b256f489ca5cdf76c7c3eede175ee4a7acedf922955e92599647b69d463cc14f2b178b88cd471b8a1c1512caa66b6d5fd8840b98b8d070e6593136e98cce9643e006b714388768920a79944be36624f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 747cba0d1cde75dfcc0b2af9072c5027986b3e3917845870c73c452858ba21d6d1615eb71ae1b5a03ca44e22845d5432b368541b52a4bb02498668e8b99dfa2eb90ec1948d90564e6ebc388ee9816e329e1d8da0d3e2b12d901d47e22e8a1fabc37408be0f89e7a4ab0f30a03f7e2ed817006809e69c21104d0efe548165f64c\nA = 5fa76e37aaf0eb3d34d4f4c590e02b6c63fc62b1d4c9e172cb0dd82409df87ecb43a1680a2764f62d13a5e919db2db08feaf98d5cb92a859dd42bca1047ff57b8fe5974fb3ac11ba2c0d8e2203750f30650db4b2cbd31d07fe18c4df84a0dfdb30f9e528932c097e89d8f8be6ff029dd970a7d2c2551529455b9131e7\nB = 111199f91b3749f8cecfe90e9b9b6951472cb701beb39d63068c064cbb2a1e1d30736026f781836a52ad0d828be6c20303c6c0bd03ad664dbf6044a5bfb67fc20a049fd37c62ab0795d836487b883768ef7c8f427eb98e5ab6621fece77b4955822f8efd190c417ced398c221215b50e9532a869eceeb605fa1c936554\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 646cdb3ed472a7b4599f02329054846a8da173000eee7533240ade4dba82ee3d7a6a92baa3783c19dbd3f76fce6b5bdd83f1f229b1c71a6faa18602e368f1b0b9f8c62bd8c854844af85c2081924c9a153e27853b2a48147950fb614028e090e2198e613631c95e565c2b9b64a43237fd4052089f9d1dd2c00525dd35fa946ca\nA = 1c8438247c0ca376f508ccef7933724df512f9e0877596f7f4ea73dcd824809bbc472749833b537eec01ab23656e9758da22ab8a4aaca1aab3fe8d2cffa6672ca0c44ac029c2ca6c3e71780c28c31b5f154c8dee782f6ba009a69d83b1a3a03a2d6275bb8bc3932a1170470fb7e405ae081f4770b535edf49f73a12ba589\nB = -e365c8edbca8dcc4cc11986a5a901e4ed0adbe89b0ab70a53aaf5821862432a1320cf1850b515177b630e12692cb025e3aa43e9acee0d8ad5e48bb15e9a3f34cbfd39d285127b52dde58751f572ae68ad98692899ab12d35e33652c4426ec60c5029e51f7e32ec3d2031032aa7b6b", + "2b63f84fb0023c81d031773f3652cd6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7a3e22f4a3f7ae7512ed73a07abb5ce291bc90bad507a5ccc0c17185804b9d231b0ae2e72bf270dbd60170f34b240f716529a449abea0b3d98ea2890a4ce3d9e2214819aefd070e00201e9f271de925c4ba59651e55174c97a13a30197e46997c6c2b152548111aa98df120a617c54b71f8eb8b0c8b4dbd5251f5509fdb8a1a8\nA = -78a99d206b4f095847e9a21de273aa6c47034c9afd4c081a8e93c2d75f4ae5b090921ff5108c863785c413e2f7b4a361506fb66b7561b8b1c5cd537e90274bddaa4e91ce74ad81c6dfbfe1a34a631dbe455d74ed9d041a9183da3bc469bdb214d2ffe893f89c3ae30f8ab99c3aac4d2fe864b891fbf4f537745fddcc60504e\nB = 5c41274e9590c1ea44c113ce505931758f2cef80ba3b10440941ec9aa2ac984b29868bece2922eaa225555dde84a8334f1caede99091165151a39538e5b7390e81df757f521236314239c213e9b874e396a022f04629c09bfaf929a0e9fe0b0c7386b0541446f6a2570491067f64e662d8611c4fd6d1c78a9f3ae69f34d14fc\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7fd27b6549494c9bc860146a3e8ceee785ca03faa94b0ce0a964844e7871e813414cf3f111da49fed1ede5e71e5539f34173d41f9a17ed129016bb9b04c86487f5def9fe350fd4dffc67b6e181e3cb26378ea15ff9b9ebdf1fc86c072c82ecd8bcdc241301daf1b774af5f90f37e45e6126c5da7dd3753a1e5b366038af6ae31\nA = -1930548d105661dc25a5ee303b61b559c4bc1f2e28b2c40cf3e25f98dfe01a7dcca0f3dead6463b55a5b2e0440a651cc9e08e125535e081c742bb3b2f8955ae897909cfca683a4822896d8a4a7073c29a80571445c6a0d53d2efe4a30a79d2fb5d08c0f95b735a1cab17ba40d71b054c9270ba6bc870e58591fb1bf9dc9b7ee8f\nB = -3e2a4c1509494f94406e3843c9446edaf0a6060144637234c6d9ce84d70fac54ed163d77d210bf557bbea0404922c8aebec67a0475a3c7b74bfa2f226403ce987c705c712bb8eb0934c2b390a173c3836378fe71a6939e48d187b27cc7236ac115309fbeabd9ffd0396fb7fcd6d46a1dc683606c757ddc3212f5d2ff3f2e450fc7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2078bb5c82a394c30a287aedcfdc5271eb3246be05954181ae4f86ad2880ce674640ecd55c2ee3f4e89e2762139586516a28558481303e3071cc9ccb9a538f887553bf5726f3849fc41ab027fb1c680ce7dee3982587ec71b3760e5da6956d6894ad8c4526d8de953c0e681ecd44883a21f0abef1544fe601743efd3e5eadb8e\nA = 40b4ba1e977825b7accb941fe0c0a49936a8a47429dfff53502fc0680d705b9fa0efe003eea3ff0b649998fdbae8d0831bea7f34159aa4c7add6bc7cd56fea97d25fb9a6a10f4572c26d792b76c18ada19b0ba06b6142c420dbb40d66be669b7c51d8cd2a5022fe1a8aef7b60965c0176eee69c32ca5023782c5410adc1b15dbdc7\nB = 1bb2f18d7c8d306bf80ae1901115c8dc3d286baf537b812ce06d6872b61e5bd44f3c53d7f31ca8461b3628b255f85338cc325856fda5a6248b7c476532c1bcdf9713dff9932a50e52a9441aff96092d3fb0fd76046a8d88288d0cd55741083a1bdb20fc6e9c20e82490273354bd826bfe001322dde9a15763f2c0e6ffd2cf60019aea\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ef21dcee9eadceaeab13287d6e3c9741811f6ea9d5bd111799ae05260b1de2ffbc192818fa45dd7befc3baf6840e3b9d24cecbcb2cb1c3d653c4aec6531b941d926fb6692f548cf81526acd0b6b0289d70dd11ba50ca8de6e174f502eddf47e57440142c7f74f594a9abcb48ce1873df057b132ccce8b364de3edf411089d28\nA = 19d0109e0c47ad45f57b8bb8519265a4390534d2ea07f969d84ad33556518b6234d40d1631be3c3cce6d59b7be14750aed114008458f50a6a84ff75b4ee7e4b826ddcb2d2293842ed29e4e484260a92199c5c66367c402bdff0f1a8057127c6ffe452498bb352802e0005e6cb084663bcfa82783a3d72f3a2a341b8075983892e86756\nB = -81fce71491eda139ed996f6a289dde8635a3a257ad6756e844c768e66746011fd797658184fb44b0e3f3c5600c56238ac7687b5be42529d5c9b97c3ce10f3219e1e451bb2dfbbb44cae0828ef894eff3b52b8dba4c115c3b471984441045f2c2db426cf5f86949d5bb7662cd40bb3b3172a19ca3fb6858315d688f13c17550e700cd5dc\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a5f90344071790373044193cc4fd92116248aacf05ce639b6aac4461ec3ccb0805ff9876ef44fa71088c295db14fc820f7ae2c0aeeffca055f8f7238c6c90db706d02f2cc43b4960abe3ca4b6dec8bba55327b958e75c60c5d1f43fcf9136f12481c267481a725eecc403a16aa6221346df680560ff316a63ec8b51dc37aad6\nA = -7a54e7ca04b9a22e2b986e72e634317ffa20f6f4ee90353d559db3f3c1bc6b3b92ac6b364f6c5929090373962b49b59cb5d87554387761164982955470cb45dd00c4a8982dbaae3a1ffe700e8903a4a8e4a21eff9d00fa496d475e0e1a205be267499dacecd31551f8a9d437f37dacfdf5a2754f0876a3e02509b78674e7ea2169c43f29\nB = 652001f073d63ddd526abc957bbb48ca74154c8f9698b988178b3313dcde9acbb19ea11a935184fcbcc31e0117d8d2ec695ac56b5a71614a12cf90f21c8882187428755b6a5f11c314ac8b952ced0f65db0987f0f87e20b82a811599f4160e65c7418af7f33604e7b8952b70581e3e02dafa025cecda970d04383ee552abc620dfb9c5df9a\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 67f903e0e5623258826b681506f3e94cc0b086e262bafaa1395294aefc9f6b6323410a44427010d5e8d8288993973ad9939199b85cf02ae0a09dfb69801536a3fa6af5ac373add7efd25ba5fee6d8f040e97056f9f6fbb45795c0bac94c51ffeaf496710b00bc9ddd8e445261d976168771060c9bd9d83838a84ee9428f59d6f\nA = -19c695ee3a4ada840a7e3626e61047c5081867b15843ee9a6506ce45540d23ad25ff23b72f988bf26ab8b98363d9a2997773604f43fa732f59a4b16ddf3a45acdbc7976a1fce01b3dd55559c20acfbb7501730f794bc45fc09b1f035d60413bbcf32a83fd3c41599049a674f165ac5283c42aef213d777ae47eea960f7727f5758146efe5bf\nB = -210697d47beb73f45207340a183a729a1e78d84bdde1c7d8f80bc84559c4aa4572ab0e6927ea175acc7a268d05616201cb235e610d1012500c8ba9351a37bd68b4ec42227bea55cef5ba7d12ffb180873ab9d33d09e6e969df99fca728dc12dda6903169acbad38388fa9b001edb09056a2ee2aecfab0468822bca14a4bcdd3a4122290ec5ce1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5fbaff0ffcfb2330283fe59611ef51cf045bc2690e31f2ad3265046fedaa990b5d5060b3c38f17bbe8b2696e527fd77ead8650d329c2e0c1f3b2f5bec4dd85641022f3e0ae6f66ce98cde1a785bb52eca796ae45c33142e8264621ab447cafe988de926544e1a7036710128c42fe8b574f7ad69d830894237d95a55d1bc7f5ec\nA = 482db04e35f9fc1d87b42bc5efe25a049ed924f816e1b0f9c8ebe34bc771e67e26d6057563fd5d5320681e1207c0b0f4b7df547cd6d5be6a2e0f2bfb088f990b0303d0ef263cf45681e0e9a1147c29f2ca5251faa633ca53f6e0b109ba69bbe20c58a76a22789243d1acf128dcc936602e832a20a2bfbfedf963bc1027650f483814d7f5e6905\nB = 105aaf563d4c1d436c6a4552770a527776f40bbb844b7701313c5ada95180160e7cd4b7175ddb943e5a22c910585dfc184b52935f06b12c84b6431395f28af2eb9ccfa66b2ee8f40fd44d753c6a83d67a6f3fe3658fecc7fb2f4a8f357c5d244422e48a33d0e2971059695a59d0d39b235d5194e919facbae7623ffc92d771532b6b0cf771912c24\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a9d204c1a497f350fa1300cbaf682c947eaeba8b3aa0450c1db9120852a2edd2a0249dedef3b3746298ee42834d869e9f765ce987a2aa4712a1f35ed10d0f7ba9cdef938b073c3a526e5bf45f3510c94ff1fb84bc77b08e2aa50f5cc75e2f4da37a8a711f8aed5e92f7e486877229cb4ff2a4d0755029972323c0b51a14fd1e5\nA = 13fd3d7cc9d6d6821d2f2b1c40c8e070bfa85b994ee8f3e0baab544dc71328a1a57b7ee57392ab6d24bd85f9ea0f2a312148fc4f4b22c589e9a265d97e73c7a5b420bee180409ec179c438a67abf37eba61ac76197f3c9ea5edf", + "2d4b8aab91e9bb1a432ef1f214c043664a51ceed1f2854880dd458ca253f09d6f6acafafec310774a672d07147b1\nB = -8c90ecd56d6c7cb129d1c9c26e94cf919c5747450542cab52281d11d8fbfcf9ea797b29588340d146cc40e77dce007b68c0c24356d4b75513b75eccbef6e22a5b88417cb6c516578d17d871e7d0957c09795f9a0f19b811db75d61c27e1827fa2773846857fec020f98444e307d3e52af501114b962ea705cb0cdf815109054abd00810dcc270d7bd3\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 57aef35a3f5388c810f576dbc30d4e4e5a39248b319b7766311157179d8bc1d7ef019cdd8c2c0175a8424abe7b33565afc0128724fa38f0900140b6f96bda2e78d7c803124cec8c2f2d6649afde4030c76cd33394fb386342d1ce97a4ecd180872134fd4e22667a687915bb4fda21f7e0bc9100ed8cd3a6668ed3a235d7b15a8\nA = -673bb11795d9d20a1e4ce8ae71d041705990463964505befce5949f895fa31c92d53f91fbc110df4e789b3f3f01f184c55df92927b8b680cc92864466ce5590ed2e98901cfb78b32ea79bf68b57a14cddb53209e08a7f430fee23f4a1475fd2640a515f8b609e98c760b4301747ecb61f1e6209b07455f1c8a7bb4e20c269e17937f39c6a2fb7b2990\nB = 46beea6005cf96a2acb16f37e357bc8975f4dad502fc3aefb4666344dde456c0ee7ea43ec493b6aecbc7aecc7d4cd107aa09e874ff564f5d59d7e12047b048c1da1faea36a7e2d02d0567bc4db41b54a75110626d13597db698fffd577a5810286ea8bf50625296ee8070419345fa269a354ca2eb47fa3108387f6a4b2c0ea3e779908a14469106eefc14\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5cdb7c451b2950c9d87638857407276959142958b06241b2010a9f93625f9106f065798f79ce5c534b9e5a31fbcbfc63cd200fc1cf10217096aa0194acb9043ccf7ced30d9f0bf66e0dfe27ee2ecc40bcd8de66fe2ed6f8cb0d874ff7b5fe71951412731fe4e19c34bee64c9312577b9e7b2ac08ed15aea753a6cd3e286192ec\nA = -1eee9d5d3854db52f9b43698e05d6a0f1d1f8df5f32884a775b25110309c46ec5c7e112eb64b2d7f948868bb9670068779b0a78bfc7e17860ee02692ec6790222b4384b9bd7db5abf29c46261c10d95f503b821a4694c45553e0dbaaa977892b916cb8990ac9ec29ab5c3d63ed77138fa1e95f395b3b233d039ab5daecb0296203166e9386d1071c61cb1\nB = -34587c2bf3473a2c5d7f3399d5ba2bb09be8105a0b9f3d8737d67b03d8b91b1c869f4e223d6246abd36d99d84052ae5894e58288a614a0da8d69f1aa57428632c2b059ba99315ea2f68ee210e65a741e94125ee4a723a7828bcc410aa2dae06ea8ed6cd23f66ccca7e85d2e071055787f230ee405e50d1519377cfe0cab4e5f97b6cb893b01134813a7c2c6c\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 95d0b209654de56bd7d6f74afaabed2cbb3247f449d80511d2d3c689f84c9b79587d78abdf0eb37f1b89f1f8dc8a83f7f9fac2c8cda1fd3fd64e16f5597b7f0a1df6da6db9e828ce7be0e876012bd52f5a74ca73ff8ca4611dd9f342bf77b485305ac28a1f8ac7538169f2bf3e4ff4dc5fdb9dedb97fa743fd8ac8791b8e288a\nA = 7821d4b65d529c30b8747e184e450cefb11b5ac5dc77905e6fcd3df64336661c82ea68d588ba616d23df485ff0658fb3376d5276027a40b392f47219edc5ecbf510cf0c5b431b02c65e5f432092f941d32ac5f71ce3496e403c7637f63a23b91e3326d01d2d32e99e0ab265108dc5e7919d3983839b3c7541848dbcd420a594e850e587f1846951852ed76d\nB = 1adf5c428f2a95c27a943637758d5dcd7ca36592fcb9d52ac0b7d27adddad5804e3edef257aa51c716801ad0c731e13c5dd000f11b5ff1b69c198f236695c1b2f99c0afffb5d084f80fdc534de3b0df4597404b50c7e784c3c55dfc9753c414d145eb0ca4d07e2f65b63f3eef8d391250a5500ef64d9bf963d7250d6906694e7670f92e3d5a7930f0f85964a21a\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 46914b197b84fa99addeaf55dd803182083a7ae34d6d4d3a55d6272af40a600563cc8d9f6b48110d0521b8b99751235bd5a340b1743497ef1cc459dccf5d6da970c4c3103c978ad2d513298f1fb3e68b24a9c7b0795f47d8f7f6ca9caaab9a9d80f15982599d764f8738217f9158517806fded5f3552fef8b7dcd2e725ee04d5\nA = 1c9f5f2a0d72806dcca92dac1450a50cba05b5dd571c2b3b988d33528d90ecc83444e3ea8df80802c30fbd5a6ec2ad9969be73aba6dd27e0dd2c842b95371d7547768916c0cb036964d041284cd323c8073095b2a8cb8797add5cd80f03595de9d18af8df7dee0d250ea7048faa47ae0131ba3f350d82864dc95e5829b88eeaf2681433dd4d58b2c6f70426af3\nB = -aa1e1b3cfd5ca0facc75e46d872584d55144620f849ab05931210b4e1526f12679bbd9cf00efdbd8863970e2abe8fc9fa7bbd21afa9e364e3c9e32f51fe66844fea4bab7f3b1bd278fd803f6bdbd0d296321e67751a0b894da338ab431871adf1514269ba05e0cea5558cd5691920fbc18237914f3dbe4b253f774e5dc1dc57023c080a3b90a004b809d237658ca1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ada55d93c533716ebd8c16e23603071950aa714deb942ebbf77206753d2676a7aaf61673c03a4db69d67faf6273828594d85e3c8cbf38460fa2af603fe9c1b6ce104854e7281757b26589f079da80685aec153fc5fd1a223004cdf30247f8398b8e92899857dd199d5d5c32412bedbf9d55f20e52895fc1dbd04c84cabfe1264\nA = -7d22392a8da1966e6cc5ef50d7409c614f8c8f8e5791778f68a00b4a056d0002707933043d05e48347bbd4d0dc1b6ca32a1aa4bab9992e7e620263283eb68d97af13b90a29c1b7dce39ec0b8a63878e8d65aebfb3bff4e67129e3b3725f999f1ec9ae92007911f2cdf738499661c5b6c9bf27712d0f29e871b17318e95c3d14b2e472cf9e466bea91fb71a493b2d\nB = 40279eefe59f954aa8c51c9c214fa07707b1d095f697ca40edb820401a45c472d1d7bb413eeddb64c14ce6144b4863fe9337ae4ae8698db92facacd6a56f3b33129c5b608eafa29e9d92dea620113051b926b80b75f320d7ca3d2ab597168c68774e68c47670458f5ef2ffd4604f20bffcc7817eb09c9057fd9989a6786a7e067ebe6724a89e7d1580f94ee4ed502cd4\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4dcae9def5467526b0ff071003e56f5537852cc0bde9d86eaed2c15e36e6429c68c061e12d321bad12e29626b5013c28f118ee59624ae2f35d2c53bfd89e6afdb6db79f0321ad5c55cab03e6a1a97ff7bd58c760d0e9fd7507de987ed2f94f9c79569fe7f03652cd53c67ebc6bd3c9e6c5672891a9d2ee11b300ed3b19753c0f\nA = -127f5ca6924851faa2340c4c8f425b1dcf41b313c5c2910e5eff8ef2faaeaa43305de2b3a65a75fe54c00fb30c0ce3e8007db1ea222521190ff1de6d0cf2e777ed61ce8211dc167bf115a77890d0bd1ca786e967a04f077c89939ce484bbb1c560f669aacf7756a4338d97cbd7f09a376d2dfd4d632bb451f52c03c05762f050ebbf112f8dc5acdd9b631292fd7073b\nB = -3bc5e9c352c46449a9155b7ce5478c771293599cd2dda58a962010f1f21d094aa6bee03f9311545e8dc6213f6aa73c08b55bcdf4d1d84fecb9eda35c83eae5fedee75b2d15a003f8a82b2b788ea19f7460fdd8f447d973c950b3b250a3022c19ff312ccdc86b6ab50c4ba627b15968c8a66d306bbdae8e88fe28c1853fdfb3fde92353f46b5bc448ae42306a4c91202f03d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 62a812e35f46e04b3afa7d26c8fd4eb168b6b64cdc839ebd0a46bf2a3a712af8e97380cdf0bfa8a274f7b73e887bb4cc73c6104a176d425aaf5352f14ee51ba549a6926bd8d059b8e3826b174385d4635b0c36df75a4e7da44c34e51eb82322b34ae00e8c712eb75b3882822bce5a2f2f5fd74355319ebe1973284c690bed2af\nA = 71c57b08127a956f0c17fd3c639bd1923ba19bfdb83c0cb9dd78e62b8fe4b7e0019cd0a6b73a334c622118f96fd6d91c1e06d4dcef8a3d0d6bf8f5beb6389226c50d14d3947ce9f24f7e0e6a7befad2e4e92dc9ed8fbb9811d908c03ac074b2a5c67b67831a350c4d548ac70810bb5617d261a045e53cdc48117b9fe86d35950d0a181b73c8cfd35edd31af031178523b\nB = 1cda2a51a707f8c4d2cbff6337c3f63519705614c26a489b545b1faf366b705af1d953701b568a684856fd3186c035f878788f7e5dbea16b5e7b6e767cf611452a4272abf2a9c5e72b7251a1ebea5098c60cc5bf649cb70980b97d48580967ffe2913309b6b78cc12d91025ae403928851902dcdaaa60f5b323a1302a5ce114cbe174e3eb3c2fb5eafc44076396c23d53b028d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756", + "b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a9213cd809d41b6bbfc2123bb84860788ce22d5b91f8e24fb616efc286a218ae9652b42912a58bf8ce596a1b48e4c72f27e52c36be1940f7d2138eb895ee36bbb917a59f73e0b6c3266bf4759ffe2ffaee3f6179492658e0778bb43c4df4bfa1a46300c9da496033142ae2c1e33333fd7e82c5a14686b255e224c51aecc2a590\nA = 1cf4e2d5924510a5fd06ff4eeb94a740e430613277149993004b8de1a2b96ada54b05365f305e896df5fdffd3d7bcb54f9a9dba9689e5ad498012f7a684d083c31d7017aaaee720bbd42382e526a35d2add21d9369f7faa41dbcfe3dae426948a402635771a977e19d5c353ec7c1abd279975f2effc0b7bc19990154b723f2f8c29e606581ab9d3966702f68d8bb8065e9d8\nB = -cdab60f9b8e1add4c54427b638ec5f76b30654d3649b500f833b2943bf6cd5d8647549657a8ff999eaffe413ed87e06267b97bfc1b77637b57f29039235548a7569fe6d4bb16ae9c6cfd38c0b8c73aa60797d0d69b03d5a98314f7f7ee25df8b896ecdfc782cf8057f038b6c3e79c99df52f839fd4eff302ddd1256e51eb31cee24585782a0439da3db2eee79a58f889d8847fe2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4dde3d63aeeee47441a7e733bcccbd4f2e495ca3c746468e9855177f7672d5d82e51da8e268ac24e8971d802e25d842a16a6b8d76b8e46a7724108c02d38a4830453408ca5ced7093676a1db4bf4c94b9b7a9531ab7c26f8de520bafe4431a55a5f5d8c7576427a0f5bf2081b998b82da2e8e959f2ec4d5141b55e40bf6ddeef\nA = -5770ea0a75ff451fc2c86d428f2569884b2c88cb6d9d407cc22b191849d389f57a5765b83adcea21c350b37bc6d750d4859f547da22ea8a3698a5cb6154b946331ae2ca18e7eaace951dcd49405bf8d8a716f7762eb242b8bf5e4c53a662c906c3be89e53ddf7a706ee2406c7d0ac17b54ff259c1bd5a092325938832763ac4caf0232e80a016cd1994441808d8db7e546de3f\nB = 7e4246ad4af268695a51912053ab6628969af4fcaf7f1e97dd977984a1604e8c9fe6b920f39a764c27d89f75986a4bbc122f92ccd1860f24677cf346474fd9441f572f769daf834e6a00cbc027e15d6aa7ec2030becad41e1068740cde82abed768de7e2cfd325848f6063e2186faa76982b9ca73ef22434a28bd2e3a5ac477af50f258140bff938d3fa02fb904a8ee0ef3c1f6fed7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3d8bde8d0625fc46dec46fc657c49c8ab12a988cec4ec1c24e6f4d8ff94514c8d8fee4a08399c6bd23fb6464a38bb5f249591456c283325e343cc289c85df0ff2c1707a6e407ff7a24383b66ab603b75e2dc3835ffe9274eafea148f20764b8ca30cbe483c1cefd51f82dfb93d7793b3ec19a57f2ba03d884f345bcc3188fe28\nA = -1680dd51d8be6069c86ae157922d55df3b58ee6f53738677bcf7332d6e7ef304ecc7ff7c5a5e1f525459d77202f3e815c68f17f9a6bf358654a92f9f9acb252ed8e9e6a849da7491f26d0e33900541ab67ce966d042607258b4382b8108729a703b429babc34496528f198a7e0f814db80fad4900fbccdfb64908febf5e09805d3a3049c0f164f0bcdaaa9bbb06df8f05309be83c\nB = -2c6c6b3c89f6e1d1cdd9abd1a9706e4f642a25738aebbc97cbd60e1f4ad79b419dd54bd14f2bd147b1d8e9bfcf92faccee61a43dbd1a2c084bf06a2ca476b3d169fa2c99794fc827b7f4dd010c0534e7cdd03d00456033ae0203b78a7ed229afcec2d1cb96892eb18898bf53584dde56b4316b3bc5186d97e3a9edcd059d7fe14561eefe4881beb8519c1cb7c3ba22cd2e13d874aab77e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5b4fbf0445807c8feec7efa3c2bf8dd86b1070638f3c87f1e173ee980412a28847b263a266506e70381aae919ae05d306d3a67a6c1e72c8ccf1c27d6296526e87f0f436c98fd1391f83440b58fadd4fb1905a484bfe8f516661e7176a268660387fe6a7266ef02e5fad91ffa69247bb11cfc1b5c3a88c76b7923a26f8a31ece4\nA = 65fe4d55bfcbba2bbfbdae831aef3dc8c8746e1d04cea174c1d336974d81d026f562225b4a297b1c3b044ccc5dc9c830a805a399bf26c0369b52ab0dd2c0ad19e723fcf9f5de2990ebe5a1266653195a2aefd9a392fd3da8c22c523a362f195babbbf5329018e3b454221b3e77cd0dee79f612f86332b1d104aeae7d8d84ad06b107715bb76bce20220d1340ecfc666b2bfce812814\nB = 12f775dbabf1c112523feab443f6e95d773e8220d66fd87bb7fc702588136a048e17ab6845a9c784dca275cfa445d007e8d8383740b156df7048650f89c5ef1a84148488fc405898f9e326cb8052f626c8881abeb70f3a0f52dd83e3ae0cb82d178cbfe8c393449caa2a87e7c8e2901a87e276b49b6d012f3cbb65641add3694fed3e3177777e78fe375f3a3b378091bb8d2998286562faef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4f0af7cb0c4e82d0e6589b24b55528818bf2164d41f58505a2b302a8f677df146f8077945dad3790c323e19b37e3379eb95de8abdadfbe4417f8bf8da643768a622ad4898513fdbc72d3b1d2791ec9ff40634678faf0e17d6e0851f08c39405907db85b74937ac403a9a3a1004013c7bd95a585728010689fcaf63b2031bc8c0\nA = 156dcadeca94985ea8bc0d1378daf1e85ecc4c7f8b6d6c7a5cb9f9ac368a97c07e381004023bc575691c082b5e9e13a02fe813a55e76196e4ad4b0f9b1e089bb71a0d5c94254b66e3e645fea25d69bbc5af266e730482a60105306d664f0ddecbd76d54e7235979aa2d806b809b3468078b5d90aa22cbd2c441198d4a52f6259972cf3d02003dc39dafdf3581638e56d08c5181d36e9e4\nB = -9a54586072d093939ad86df11fcd3337ad7e9e478dcbefb2b89d7555883fe8565abcd5b0a9c88ab135ce5327b2a326db645bc7c0e3ce24f902544675ff9d946abf30302f123aeed0f4e28edc72758ffa760277caaf4817a3ae8615784c81896d2404e2cf47c06b09085cd0ad1ec46cfc1f04d0272eac29e774b30f19939d08c036b185983c93ba15d1d27aebe4a357b9f6a298acca3940d2730\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7c3ac09486a6fb518b98a9bc8a8b382bf2293e2c1154470ff7961212430fe2dd28697e49256b1ad8add082ee27b6ecc016b120e971665be801b720069d30c0a8c6ea4795613017e8883e5c0d0e68f982c328379d7a0afb7825c553e087b33e9d78f90e0b95a6597076b8ec2c1d375e2143bb778c318ca0680a64072cf9a4fc08\nA = -71d8e7ef13d63b4f417c01ec1241020a8ff4c9b2db531500984fd3e45d22b2bd581894c8a248ed7cc345e70a5698407df8f0e4ac71ed2c0d42122a4f92279346f463aed899253206786928a0eb7c37f2e51e1cde7f97cf9288d85c3ed7f49e62af0bf9abf062d2c6544d83b9d3438b3881e0d07b1fa0f2a4446fd43ab3b4f81fa2cdaff199c87965e298943c68cc15f2f3f3225efad68b73\nB = 64d52de221f102af62ab1e9526935b005c81658f8fefa019bc58e641023fa785798ed0dff8f7f999dbcc2ecfa47d5314ac6676c82170d6f2b18122c17c1e1ec1b9b54e333a184a46ad35b2150c8165f0de19a24b98327715e5a641c1b6d3ff9d247c89c8749e775e6fcf5f967c6eb5e73523d4f1ec12db7321b14398f26201a364e1371f0ac922781ee252c6d2b3c657ef259ab73cb7992a370598\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = cd08b388ffd41d0aa29a3dbde74106c57b18d325be8f446a2d9ae95fa4144037dbd41eccd50fa34096984cb11bce555c117c5568d76a8f79d308ce11043fe2413d37d6aa60c366af6c1da93d525e4b2d79fc82c0a53ed62fbf72c919db8a3ae11f5ff8057d7501f5f6dfc9ae461c308d21919d0de9e31b759d1d8e3526fee58\nA = -12e58708c30c93383cfe6e99ee3c5caf1900a7e610605706e77d8f428fd59db2884f5021d7a382cb18b75ed22528961cf43be1c700c581ceac3877e83eabd860583e6e94f3f2989c179ee5047c82b53d37054c9cb7ae08be60a91b10d49510e9f0b90ddf89f93790c3e18cccad5a9d223c605a6c567550e2b4950e184fd97dd68bf30681d3f9c585365de2cadf36a43f5a5305dae555396dd50\nB = -26ea5079ba7ed137a14d00d413d6f818e911cc183c88764de4d91d7a9b4cc7af3fad703142dc7905992eb8bf489f6d8231bdb25603ddf3c31fda8bd9bc4d78835f9ddc1e6445037f05125cb1ccd92eea2e927297e5eb915d5d965a25e5d58feb8d79a890e6036c80ee91e7469d9eb672d7a8db68905d06f5981fc40bf486575a067d35cf14ceee3ccb79b72871bf8f52b92e4910ab17e5e59ab3ae6f9\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul", + " = 34714506322dccb91308c403c267f1ec75f80faf3cc4272dff4a84c13eb1e6133af6681387006c61e7e087046b64e7ae74eea8a3c0564a7c1f381e1c940d92b2c766fffdaa7318d07dbeb877943a73b50517b49e5117778b8a60212284fb92f29a9f5304f8f537e88acf8afaf01fdf64773f988cfa9551d6884baa70587ab76a\nA = 638b7c549ed14256956bad532945ef9e11a50313172965386635a2fc7db79deb0cb5c157e9854117c17f1509d505d01a0e138d2e510dfcca45b4f7ec968b5214a6699b61b8ac68adf64d5394f50d577a154c013612090e2045462160d1f552592197d7da78e03491ae284dc9faf643805f2674af8652bae93ff230fc3eaa833dc62781e5f74d0f0b90290d51d481b0a94ae6e972197c6e84ad7ae\nB = 141f62297ee88ad527fd1e0e09d9ab5dd80e17b32f34a674a27b00d719839701664ccca1b00da2613396cf633b0bdc4482ad3a0c3e209eaea7c22f33706ae44155f527c9ca4e341e651760d1c39f65d5e99e649d013730d2502b6b65adb8a73e6bc734b7d879b430798dcd53fa6c0badd57896cb566d9f1e0a7b3a9161e9808e762ca819330ce9319dbe7f49bd663a9f57ac53d65c6851dc7bc4ee66e08f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7adf54c77eaea2a1743bc5011ace45b7651846e77f90402297f117d8b1c0377f93f49e92a2457f3d3debec3022a96c74c166d01b2279553ef518ec0e612bd7b382529184640c55b89255b2679da9cf370913351592de39f804f1724de36db90c045fa644e8ff20627f67d6afd4546f00d7af093f668629f9a06c07fab5654ac8\nA = 19c491d5b55aa25f2e18cfb7fda18ed4b020e3f63244eb9f6c4dfa86eb8a70875cc898e305a7acdd3eee081300edb3e4c837940bbc1927f5ed9f651e46581639e133515457464e9c451390828e5e7e00a688daaea74620363706cb69e02717489ba9ad05774c424c18e295278caf4df4ced80b4cbd20cd631df43f2e16ec0334564d9dc03dfbc7111e4252504fb449d5a25cb13630b7c0c565a82ea9\nB = -c3f765349639beb80f888d9c8b7b335ab46b55064ce2a88180c80ad280c6b7314df52b7e73095dfd82896e24604854a48121353aa1de663eff07882771803010005905896357cd5a56a59f0db0045f1aa2c0b5626e132c169abc64b9893f95932f54c1d8cc25f215a9ef6e4cfdd6dba85f6faefeca81793b2258ae1d1427e81e458482aab87f6563abf435be69a05b195d1eda90146a8cc92748ca6f798b10\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 32ba5fc81a7747c3d812cf036bc0edc49f08824d53b91a65a6d41edfb1651d99c11ccb4c074d7f04e652276ae3fdc8d6eedb72c6e46cbb1f7f4070dc9d179ce3e21a3826f7dd2c27943a8d26b192d7f5c4aee9ba0647e406133e3e89c262d37cf468aa3ab8c5dd1b8900dd06cd600abc6d372d9408497d9e20c86a9a6a4ad9d1\nA = -73958019a5a52357b9c1d954c9b14f51ddaced32a4d7b7c95730697cf90029564118ea168d23a54381f7bbd6718a6b662e4c87410e48ac53b7767148582b0bd6a3d35f488e7fcf2b128e0a58b5d468dedabde4d624f4a82e808dd7b175af0d3658c6df1ac0da6495bc9a8dc012f8de55c2003da9b2d478e1a089fab776d99026684026968fc309dae46a6ef2412039a8207c3084f96b4e38e4fa01d131\nB = 4330fdf00bc6d13ffc267073b68aea7419ebef257d63f8f244accb9ee46edd04fe5481292de69d377ba6b6304804ba7ec0a063b42339e6e37867261b9945ec705d3a0029c6f499420e02a773476546993b3c5e1efc2417f51afcec7145a9c2625496865c11636e285d4c8b053ffe66887333c51a712fe9c8ea57606103fd689dc88f1fe37dbc33ae4e92067c5bf51b53e2f8205164c800e5abd677c73949b00ef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 69b850a99b471003a56931f7856da357a2254ac50ed81dfae019c9b722b95af16047a0d5422cf7ab66ccd898e85caf0e03e74cc8a5a413661e5da483b3f0363e63a7031bb30626c8f73d6e99e290071094b7fe5bbaf4d303192e59acb5e53fc7cdee78576b51595d9f7a25ccf3c7f8889de68b9deec167778ca27ac9d4c71c3e\nA = -1976b3bbbf92acbfddbc05b5d9e7b62a7666b239c1e6270db7ec6dc2929bad1024e745b897840853d14cd815aabb01aed580e1cc66ce37f9d1cc4c9bef8ddd35d28285faa29f2003d2a4623ead7d73302ea9f380f16b3fc06b7c2b8bb4ce4c8b03bfb6056a61c620e4decc6048cdda5e2d3ed8a13b779b8829e2bbab91e9f6b0304b1c08bf8fd85e0f3cd7ee72255e5342e077ababdbb545d7f809bdf8145\nB = -2cab554f7a5d21c499a1025f61e6c81ab0fc68a874bf60470cfac57425a451365be62c380ddd31f6e202f29769e2b6106868da7c81522e03fa6f0704522a5f8bfadbd007bac65595e149f6c585d7fc022db016bab32819049e7547bf85d4232a7fe19084907c528e7eb0434f2e5a375ad9b7d463821bef2f6a721a635252576c176ba42519bfa5d97d0e47facb4426aea0d755507dac81ccf1537b1003ddbb0727f6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2ce33adf34f2249f8a2d2e073976cb4c78b71414e027657fcefd56fceb022a06c1969dfafd519eb9e2542662c7647102f5c528734dd005fca666be57b46234123bc3db286cfce07bcbb399eb6764daf2b9aafbc2898a5ff43ddfae849c7549289640edc4ab7c4b9fcf5e159623e5497f509ad6f0270a41fd864c9437302ce380\nA = 509f5d5b160e923b4fdd72f4d522a713d780daa4bfd10ddbd62b26497a2e7925c495afc2abf0ecfcb7980e588f96c4078bde51c7b2c19d86d15bbdad5de72fec2e0a284dd693ce0902b40e54af87ac5a5df38ae6d1d882ea6299fbe6910121ebfebd06b454ec5f855bf3e7cd544a4b0d9a764428662e824e2a6185723534f5e6ad829734347d240c48c2c0f8bd6be6ae8a495a9e383fbc7402a4096b8c2c214\nB = 1a3b7f55307031609afc974857a6cc75821e73a1a9535bd6b8e141437c3fd4a6871c904e22c5d9289df7525ac69a0341d3620bcfc5f04b38ae540e26beadbce0002a8a8bfd0f6a270007e4c52aec2fab11fb2a831b9886997256e4b7e7ad3b0ec64c0f31fb0d637869143712291f5073a5756466d7c82c31e08e09683478229bccdedc2cabb7e426af9025185d8dd5124e08afa4e981236180e0a390004adb7918de6ba\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a81fcf9a18ce476a839c896cc5d9b639fb1d74610e2f618c25310147b57cd77806c2aab90be7be4ed10f0122baf9b862b141ee8e4be5e0c23ea776267f14c31e50b119bdd33f2b41f6a4c43d35bf6f095864593e0d8c0f1fd4656d8371af844d197308bbff14e5a28b7181eb6e6a2b31ead7361e287f3b4550ab0484bf7baaac\nA = 19f1ce60ca50bfdf8e02313f1c9a45496720a2ce467f1e8bdedbb32525d762878b61476989c7f6ae8dd29c983ea596e521bd4cbf74dba4d505dd9ea5df423474fa9725d5b65f1575d26ead95725e2a59a6c8a5397ebd6b54123e42bca44781b84c014b8e5d2c1a86cf34d764b242baaad5be285cec72ba8ace808058a0226c04f95eb2b53a828d0ac41e6b40e5a4c4092788d9f7e988752f175f075d545f421205\nB = -b115a1101d97664759538d22154de4b000c008e551e2ab10ad05f12274b10a4cbfee762d232df5188fa1161f37ba61d146e8b95fa715d98e016da8beb0600de65216cecf8b8816f6e7e73e2a2bfa7d0bac74b517b906bbc43357fca69de9cb5507bd95205515b97b3a4d6842f3d7b09606cce1c7436c462f49dd05e915d04ab6fe2748ccaf025bd5d19749cc468d228ba43452ccc479c146ac6d781717bb9966bf3835dec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1473f092540ae30de595666beb33e430cbec42d7a28d4f7982e62f58025cdb617cfc33f1e5ab93d2ebefd7345561b81271bdc50bfbb0db6381dc0ea023ff7c72605da26dc7da2b5664d2ad7967426ca97b3745f82528964bb68e70087e14dcf2d71d30fa0d1f7b3f10b19b357e7053fdf22bccc5188c6919eff1e5c402b750a4\nA = -68f280cecc512d51ae534f30aa198cf7b170c346c1159fa9cf158d0127d43e50a8d4704ec54b8b4295dd7f51c6771cb5767fe0c975414cbe6d2bb58ae66a095e8832d5f443498b1ade1f5bf249da58595ebd878677b34e3b4c99ba6124e2b71d86a8d99727a16746469de51b0a61d9d981459a6cebe206cd36a09f00ffce7f532e2c31999847ba000b9e01a4b84f454544b6362a5c093b9abe9d583716f4534f2de4\nB = 5b79684387f18d7de6eec3a63d737490dc2a46c0616ec16388dca2be60adcda11ae13063ede3fec177171a51dbef430f8c4b3f6d297b9d6c020fc44e3ffab891d0d751d033fda813861bc067c181118dc613335ce89c5960f952e5fd28bc72c41b7b6e374ec29b837f1e00271cab646c794579d315260921dbc3b984b86d98b8f8816aca4f16de50657e4102f34d9e29ec3a03e0da06e70f69952339bf2ec4a7e74daca82239\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65", + "c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5e4b3f4aea7115d592bde9bf7c6594fee77372ffb19f7745b4de878a4024f81e8290c77d2915424df20004a7abb64c214104a3123e7c8f230c159ccb99bd937521b433dcfb065b186a685fc40f9166bad9380a02e297ffd6a307ce8d2c8f2f1330447a9c06c327b74f3cfc2e98f3351a8b385bae855941228969d1c29e9da3e4\nA = -11c1d396693139df5bd91825c119d1241c3f57b7ce95b46472dd82081738cdeb0868d18eb7c8ee7808016b3311f982adebd5a2e5f4e201ec4a34f3037d260fe580e771222de5a1a67947a4552cc03c5c59f9e60e25063a702ad3c3aa43f061a22567f938a91f1dd697c3e3978fa11ab1d65030bf327f8049bda745658bdd4ba8f3e34b060c6a2c6c5a8be54c7cb5f6b106f54a37d2be9f674f7747744d4350b3acdf373\nB = -25a65b6acda692ba3330d70dbc3ea4dfe208c0df358c50b7872245a909c5ac19ec568b1a1340e1a094f5b8e7d1e3b7e04bb4df002558aefd4540135d62d75bd5ce959128c1300b9d98429d7369610866d98b22c345e531f2beb80b042b6ad48da077043401a82e223e9e529e7407bfa466dd2680973006d047d837c26a60cabc36a7ef538f603ba19f8e923f168ebfc3834df8f77a559c9e0342e33df245f551bb242e5a66e5904\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 47872b544fa0425981ae17bb450ea346135e6ed7a9de0572ae14a6e85e8319f27cfab778cdd8cb5f93b417d9c66ae0fb7bcc6652620f7f3f74acc2bc9f2c090129fa8315aeec9ca7adc5356484474ee803883ba4695d7bc47c87eec508d16a15150cf3f757c4713de71366e958d6af045b2d282b6ce96976692c80b1e0b6f846\nA = 7e8f55c040862f12d8cc6e506608eeca65ce38e9e8ab18ef7007e3cf0f1c9a0696795bd10f8e1e1f55bb4f4f3a35c2e0ad18289e250571ccc26a961f730346efb1e29fb143ed97cf72deaab19834fa2e98e9c12ae4cd23b9c5ecef4a04c439f7d42e110b30caedc4334372ca24cfe4171ef1430528f7b57bbc823fd606fbd30915c5817e6c57c967c4c404a0847b1455da17effeebbec3f9357358e00001239aae209228f\nB = 1cc00b95f6bd3abfa697400c98110725a7e109aa9b8cbbe9ae16327c4fc8e5bc93afc7a94da32e98e85e4fd5eb545192c73007d97a4e84ba64fe187ef61d17f0941e165c9fe64c7b8054e24dad30f92b50d1f526b4bb031e6b1b9058be24884b170a145212273c51692b71bc57ee53176d8702b975bb6ba96284b462da2ce38e12d86b342c7f4d3cd489fbce88a309c7df1121d7bbbaab6814cd1e54953e5cc46813ead98f02360372\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5d193b085e57c3f1e825cf3b36c8bdc936c603136bb782a244b04a79fa713dc7b08436b85ca3b483d2e100a012d6430679b30c8e4101c8f08ca0f9010dc0f27fb37be842054dfdd99362e03a7f55ae58db7b47f694bd35d91a58975ae1f255c41617e773f91c2640f768bc702a213f073682dc761e056b34c57edd85585fe04\nA = 1bb1c759ea94b61a1721ef5680f42af30fa31444b27591a03b7c9bf5b90845ab965339f463a78bddedcd62fa21197c32d6850c61bae195f86e1c7a23e7a20dc618c59ce3a1c6ea6306c0b01b11a36d0fadf8214c36a133d689438021ce7c78b20c85256ec607360cce14f139513d9f3ea6eab067b1ffd0935d7c43419b93ecfadf2c5a902b7c39a69bdc023173bdad574adc77706c1a666d66f69578a5bffdc7cd6eee28ad8a\nB = -e8072c49cea603d48f20276df188fd2fb28f8721d578220cef7db1e56379c04a6b372e56a047cbe59ea84ad026adc5d0aa930011db63bf4959f15781e060e0240dfac0e2a2c26be12a21e5650d12140bb49a2a8e0f6a86e4b1eb79d9b8aab3202bfd339096529170cfe3e0c18263128686bd9305e92a3c43e1523f97d8a6a2707773e3d441da162a79089c9ea1e094cd5a23474121188013c8c287965a5e77599f6a7d64174b06cc165e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = aa79c899c2b9518857c9e4f96523a44607c3f6a97d1f40d6474ec79deb2feadd955fe92d789df4d362c828084559fab56b5e33a971abc5449208d31671c7e220c5945886e33ed1d804c059a8e439a92524a785076f9730732bc5a152aeffb5b9ecf3a7e4b55983016355c4c29827496fd4d7e6532c270cb9ef263573e4c63074\nA = -41b326c2b86e7ac14a2050bff67bb5bf9697f02594789c4a2b3e8455df4522546278d0620f28a680f6a88ab545de5829305485422f4e70a5ebf0ad15508dfe3f16ac556436d8fe8a8cde83ead549d88e0bb24dee52ebbb49159ae71589d918d3fac8011cfc3afad613ea09173856b7b79b55a2e43e0f7cd21eb9122d5f6a1fc5408414f5aafcff863b870c67b740256d317a0c58af9a81d8025a086a1f3d79f7408d4bfa06b9dc\nB = 4730f03c389f9bdd92fd864177e06140c9dcc02d01fe7d37b51d44de140696f116d11bb67adf7db797edeb7c304386a7f5e37bfac46a5462a6d4c49b1bc034c2e0dfa56f14bbd2a4bfaf86bbad4f6d0dfa13c782fe680847d4b43373d7137f5c2ebe4ad58c695a7d4c407bfd888ce04abaaec60a3fd33db10eaba6b6acf0e16cb61d1beb9212c2b07921bfb5595ef1eb389200b356eafe8b5288d8f0e2cf252b38301de65190d56bfadf57f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 23f9850dccd2af799f18268c3a2918a69019513c55268faf2477c50677fce277d8ce58a0cc06dfe389170faf5f0ae13ffc4954c746eebae66efc14eaef2c2ac9001f3c7ef7e32fdc31dd725b6a8093e33daa6d19808908e0c2d3e7c1c58e0fe9ed92f4d7cf3cc222393ca4f95feab5d34fe29116410a1882dff7cd92acb87590\nA = -10a75953e5fb9903411869a2949f8f04144d6e2d61f95704ff55a02f40c4f283add405353a68bf7d6acc1b8cce738f0c6f9271a538b4c688dbeface58eef0a0a1d491a9e66958750db97bd01466edfd245cef03bb6a3acb81acc63c38538e7f15deefd15afc422a8641c357c31a069258dc0ebb63f06094ed8fe7d4d420246b40302361967c81f0a9ca542fd1de01967514ff2565de7ae3b4a200d63feaa22fb99a251cad66624df4\nB = -351242b6e6d0122f7120deb8357c3bcf25d221a15f83579883bfb4dc2e6099e6b7b95fd08f6e573d93354b0676f7bc9fad563d6eb0f3567ef43efe3d874b9c7733e4fe1ef491043e1f80aab6094cc9b9c236570972233ea74e8779a6eecda23a65d08d878850cab6005159265893dc0f66920a12c26dfb421ec326a1ac09e9ab8085825c31aba488af02cd51f96b205c50e692dbf2d844ff0a989c3ba9f1c2bc7f2e7dd9458a72d310eb28d490\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 69c7fa326630d7de69249807cd8bc55c9315acac26fed3caa3c8a9c6b51ee96a7dd0b3bacd5cc13c15f199e268c5eb91d1ec36c085f83b437b9906caa6e39ed7bf09778610b621426cc8d36d96f541d0bfcc7693525d33e0c2ecd77ccfe80289a11155b37c7ea7791b5c2be3f9b954e230c19d746575afe9a1a3a9677d23c5bb\nA = 7cb78ca8e5d903096630744c85975719c16333e2e44931956d8c45b001d35ed4e184dec88c9e2167d2f338fe6f25540a144cc419590a4ac7caedea3bbbc565365d3357baa62fdccef2c5ea616614e0bff60e81916eb4abde0c9725b1bf6869e8b1e11f6d0d08fd712bc68003e55ed462ad4946f7f982e663f65d45c07c659d9620d5139d2b3332a68d33aec36e21716a3b75f44272a19f860e6ab3864f06def9a5ddeed340ac0733353\nB = 16d5b074e008fdd30e73ea95cb5fb87de806319388b3a44f33c94d38be0e6f1a92103dbdfb3d23b6e1d19bdb29ac14833003e9482cb7524d0d7b4c377f4911e3372f2cea6f84c938d84e3994e80f0d68e7e385ca29e02f70294c921dce7cd3829c5854ce51d1f4fcf7dba910b51b48a3f53cb1f187182435f21f6981cf8440f9c8287a9749c92c0304cc2bc91eef32d8e6526be802de8aa16684e8854cb0b67d9f7ea00f6f0145d14e3c251f70881\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 72192604b2f3f68b9ed3e261120ea52b06a05869f6abd21828ce8abadb3a71c360a14947bc738e5d1d530b9636d796f785bb44508477eefa80c4b77d4e8e35463e15ea2a48c682d3288c5abeb66181e4bed7d5b4e0db20fdf5ed68513aa5ae7e0978ec1c4646368f206636ec90e808817bd1d03acf9adb9ba57dc153873fec11\nA = 1112d291463b28ef45e879412e6607a3e20d50dba5044e71883bb3cdfe9bc694a577fd7d896dfb836a171f3a4d8fd025d3a979b43e41baafaf7b535d9050e47f4880828640e952435648960bbb74a3c25dd90bccb3fedd254dfc0f031d0e8a468e93bb69f771ed35f1653cffea1a763491fdf6efa21aefc287cb611f5ea0085f64cc3705c784f87ce00846901833d01a3c45ce047d822ba390b538f0a24720155409f60ca0d90e13991aa1\nB = -d553fa2dff0265cd9d083ad097af87a99af3d8d93a9f4c07440a28a427082004ae5c81d22bda1dd2429f540de8df175c1b4d0d50f0227489ba570b28baa35055df951d05b584ae6b051a135d7eb2a501b2441f82c135a8ec0eb81d379b96ef8f2fd526ee62293bcb934c76ef8083727a4b28bbfc9f", + "515ebcc2bb7ed9594a106e137ce94e9105b2e2f4776aa9c6abdf426a181181fece3251c3ef4f8eecb634e6bd47c5878663fd51c74a66b92713fb7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 459e19faf105ab17ff794927aff86196b3cc3461e69cada53ab8c8c81e2b1820408421ea1af6ae10257e8cd9dc16386906410761fed62cf9ddcf0da2a92800d99563fbb9cb1ab0ba46a17cb9dee3f2b68992c2b832a5932e4533fbd5c4487d870f3fb5d7a1c358f4aef02993360915a9e9cfde234df5f51c761d84568400b618\nA = -7a964c62e38e4124cd2bad727138dd12a086a2bf01c095b078ce2f81288d3c8435ccce0c8e00229184091130989434bcd107a3a0787a2f5f4b0e8c23b1cee9a8f39ea279fb6081efb6c3df1704fae9e87d63ac6eac4c6687b3551ab7ddac5ca0541e12047d04c2fc760fda0916cd2b585a90d25880fcc1bde8f0a1a413969938d42e8b3b5f73118798e85b901c2e15860e29e2ee8b1c95336b97dc10a21f5300e0352adb60b40a8a99333380\nB = 743ff4d91ea3e0f9c4f72e5daecb4fb00b15b86e30bacebbe4384324523d14e22abe29b00573733f594d652a88d98c987f8db08b27b4dc68577784fde02dd410ebdbfaad9e9afc6a22a8cbb13a780222bd212fc61e38faf409e940fba35ed909e6938e83b0fdf5b5e3ce138604823e788efc3aa0df924554fb70fd2faf8249e17a827c5d85942005b328bed97e5ea1f1810219d77f2fe121ce66518e37c84d64aebda3c397684212384deebd520a776b95\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 183950095d9424b0ed09985aafbbd2e5d64bf541a56b68b42ea8cf9b2c051615ee7bb6c0687ca6fb0036888fbc927cb7aeb303750871442ff2c0087a95f4efad568f48b03bd2b9a9ac26af8c259a3fa97cd2af7e3d8f36148c26785489cda6c00a21e7eca219d1f41b2e82ba8e2c1cd752eb08a2fd50c6f9077f3096e2eba05e\nA = -1d2fc778cf44c6992d1f3a056860eeb12f969358cadb087dcaebf5f96bec42bc0aa98672260adf1732da057e9e0d22081e33f5fa71f248cf89dd361036ad58692637cdfff584a191279f178242ec0ad397efc52e99462f496caa0f3133c4238aaa877fa7094662f080eb284c4cbeb992a368c2d157ac5c8c9160c167716406190fa39ce0abcdac52c8020969b87a4f84bc09a51f7b2ca288c93b1aac64e19623a7d9e69976a31074f637e4c82aa\nB = -2f188f1245b75cd21d052ec76edeb5881944a143fee31c67370fab0420a748f3f1957bb8332ffefdeabd0ca806169629f130c86c99bab490a9668fd8200f4a9b1704c589e75b5c8c855f133d50b2ce06191875e2872b36c78438d6032d53004c047f49e4cb81e19fa84da16d053e6cbc7c8eec0b9129a8831eba690e0542ca3fefd204258624e92844c8b7bcdccab986475a47c8b22e89079ea6580ef8f496099cc24dc2911dcb1921d1451e2163b55bbb7db\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a02c38d5df9ff7055ff84122342ccdf6ed7f7d54fe8227af091371f5ae62844645586adaae99c11f4ccd828103a81471bac72dc20625962e41d603e760591bb3569a21f45bf062b86b5fd1c617a4769a4d767a0ee14d104084c12ae875316a8f2be7adec0104381dc02c20b5851efdf7d4bef0d68076975e0ada3e58e101e8b4\nA = 5daf37d616da184acb278a75fda4e4fa49e544eadcf373c054b203a309ba198233f2285a1b55dc92e05d0213b26c82e261d8383a845813077b2e1b5f4553400f09410987c8dd21d4383e0f05747d0482d1a89f160a5220b22c78393873564fc5b1e4d5627ef3d4a05612709f301381df35606e99560fba07a917d7ea7413110fb5a8290e114d5200cfecb00b6c53b2ee29911bcb2fb2930eadba0ab9dfaf46443370307d9c3b61a329f0b8b8cbe7d\nB = 1d9539fdb1afabeb9be6e774dc7c7cc4bb4fd63af7abb557a5fc80a3fd23a4600de3c7fae89b91f3d441b61d3e24b2fd3d7803cd71620e7313917b4afb89ef5171a3d8a68c3c74aa3dfc8058d555eac429dfb6db40a9e0c25aacd2050418d6f32bf21cbb76981269dcd5883178d4b69a931a0338b93022a2ed0f78f3d8877989cc406f19d6d082ea344309318c56be7946412ea0867c78418ec32b9fa3a61017c10939c9345021133116933a3d1eb86a3ef16424\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5fca287abf1f487e0ec18c230860eed4a2e550228b1500b1e33bcd6675646b5afe505b55073129f22352dc2b113c584ea1b98808214b6916933e90e036b129b61657cdea9026e1fa087ee300e055ae8f94ffca933a2d70453ed220468a5a3cf1a65d81eca11cf570d7d038722397f487af60531f24a5f069671354882c8bd2c1\nA = 1d9fe15171dce97475f4ad329fc8fb5469fb2b8086e4b01eddb6ceffe5324cfbd28d791705848569739b6758ca7e7d7d49adf0c11d891b0a5879ca870d1ca5ff475513322ff218cd26024f97623bb8a53084594e1fd64154e1db702522883fcf4c0d677a7fe90096fc76dc3800816996308d8f0be2dbf3b879f8a000c0ac534511437e2ce2d7ebcf42fd1698a829eb846b3afa581c24d5bf97abc6e247f110f4e872a2474e3acca6c8c0d518104c3375\nB = -dc0da8f7adb8e9f7b0e3f293cf623528dc8e9668317910417e52301c50c62e7d30e77ec7e38d6817d1f5a93e851f8560f642f23a0b9f836812d27b1b41c0867088a3108332b8711047560052ea30c8840f03a25c65b227a175d8f340095823788adb5bdf2b7ebb801e20f6b6435e154f78d17b8fc4373aecee56ec7b8f5686a7d22c8571797fde85cec884d45ddc4b1f2cc47ebf56a879bf286f349a0edfb531168b733d43de3b86b49eacb10b06a432c96c63440b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6222c1a14c6390d73944cead58eae5e7a6c19d19e4563c36cf624f5b61d99991bed7dbf6a0723abc56469eedfb1f7982987c2c7af6191178cf0933ed5f191b8117c9d726cdfa8b82a2fb25ca5436023f5860aff5fd482c611f134569ae87395dd99e5e9d400b5ab1e3064210ded096411654518110ea45899f4be2516e35a229\nA = -7f6766be6c6ca9bd1fd7ea1f80bfe68693f7ee4b5ba2946846839060d6028eabbb9079a165c1a07eb6a01239f3f14095225b8617753a1cc3d9c1e69b516d8705cfda396f4f0d05b0944a0f08b478d261e968c06918914ba87c8e7b7adef5cc2a875917d00585571542af219bd726e502b7f3f0bdf0cb1dfc6796be2e22e8ffb5b8bfac7e15e991022974e75d3a5eba214ab8a1aab2fcfcdbc6ded2abf834d1899d2e3ff94bad9c696aece045212531773f\nB = 49c6f869745983cae44d33cb7ba141234905441ca53172abd1a2dd8bfeeac4b236605cd2dc5b04ff9aa13de84872145b935b85479136065d2d57fd15fbd97480c25c6354636c17ffbca33c9319d65e82523e39fab49321380a130fc160857a451a69b1d0509d5718a9cff8b49c2d677c1f66bf77333d2511f58d3eb2fb47b3c162cc9be8b012d8df70278f0e21123a69724a1f126369a236d54da026ebe222c513f24b577707b5ab4b90ab0e22b4e38ceb4181d4ca101\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9e9cc8c5342dc6d6daf55fc9aa9f79ec18592e8b9724a66881c379245c91f06a7df50a6ba0964603a6dac97e77a55d06efff17c93d5faf107fe65788d0f56483915f6ea0f1ccbda7656eb58fc032b5771600beafdc12c2076110a9b9670bd0754ff6a72c5d6e1a9e4e42c688e1cc96d7aecd815bdf5dcb16fcd1be1275ce7282\nA = -11635fe16dafce21efb1c599305e9a16eb5651187cbf054cd9d911c13e8eafbb738013e212f9c2b3662ea15ac9bd82b5751d43a38e4475d2310945a812262309094ae9cf59e0e9f3d02c92d8ab01f5733a20f051054a240bcbe3a7b6bb3f7c434229f631c4af239d33bd3ce30a372a480fdb49b2716091d26071aef372b8bd8ee8eb7f2965a372a836000b3737d2a833a39230e721e4844e16031ad69cd45ced60a64510c1248fd776611934d8d2a913d965e\nB = -3bb2cde9d3fda96fd7e6b24645f8e00b43affb223f2b5c3f4b7cfee905ddd6703a9d6c01f1f099ad1174da215a645ca4707d8156e762e2a253d7cfddd05ca19823ada9d33924013f677cfe4d86bde025391e0aaf91c6b776a9cf8a09dcad7cea59ee7aea1cf5f5bfe67c9d4456332d1f98e5310db9a0230381e1867a8f75b8757283f911f1a5e0d4afe5d544afa8d86637f9c9d87428fdcf8b4eb8f477e617960948253b24565b2f23081c47e211cd3c788a92732a49077f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 30dc89bad4b449d1df9ea9b8f9d40b323c71d7e1133bc44d33bdb87c38cddedf83bb849e83436e4c92a06546fcf3e24ce6cc89d2e97a48aff2c7e3703da1b167a112f662a89742355e11e131e41052f1b379753cfa32cb0efa3a07465a258c585cd68c86bc9a473f5262c86c50992aeccbb9725b69ea8b3a7ebd2b6a24db52dc\nA = 60463fae1e9354559160d55a453c12d75775a5", + "3d1606d1fd16bef7e4ad1c78f9568954112f9280c46781180951534c5372dd5aaff3f33ac9c2e0ce4934d7009aad2ab5d6a5e5a141a36846e8925c7a28d116c68fb78aa9a687ec9bef173c1b69e0d7261f96eacacf237e1fe5874e5d553985b0fe7692ce8f2a5feab9ad9a2ad9c4bbf050b73b8030ebc36b94af8c6ecb67f8c94607d80cf600efd4ce4aa006f9b1832da8a1fdf8a564be0b4369149e8639e1714\nB = 15bfc50290b771ad147695a4c6701c47f2e8aec0657a4ef999eb45685200981b0ab5f8abc143d64878b85e9548651a1afd0913e3b14d11d3a26ab9793596801662a67b0062fdc8888feb029266f71d170518b6a4a040f59996bd4f257f221e830d0faaa9688aaa6afbc1f9b40d25097eab9d71d80aabc085f3a07e48bcfb37119aa00de60be55fd07d5b1281adf7b98bb589cdf2026252edf2f075ee176e23afa6b1f924c9fcf3c34c76752e833278a2e6b62017b88b77eece5\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8b506c9bfb75ab7ab420ae6c9b371ef035fab512188d9df76f0b31831573b44cb08266186a04d20cc761d61b6df3e33ecb86c269205c2c79ae6aa4d3ebacac8ec71d9bce1d7ab146530b131c9038041c6ce8152a6f1c09b9bec8eea4462dda0f08d75edf296eacbcefd62a0c197ed30f799343268bf6edfee4995958db7e0420\nA = 11c16713fbf8bc9696782cb5a88174cddbe68a04e8fe93dd074aab33dcd85f92baa178b2f3b8817be0cecb802cfd3ebb06734c9d399a1f090e3a8a2110aebbba0e920427bcda74bf11700b945985bd532286d44a1a615cf7c501412e454edd647f8371cb8149474557a0d47cbb782f460de7a3cc28991491ea0fc510286711b882987b09341c079565414f2c930e7c3c3a3e3e0f1d786260a7f45c70e0fa20dfc63849906af61707cfdf5a9b7a4291a1c1586d16b8\nB = -cf5638af39c6da3757a09a92e0bd54f852742682dc91c71dcdc6e72f7825a0979a1ead2e158479ce5565d22472dc3853e6bf7ba43296a5e0e0a355f0703cecc02ec79da83e3e9de10a6eccb858dedf7d4c400c27486a5b8cb34d787cde6a5fd271e83a6cf66057838fe30db1f30663cdfc22ef5d002b0b5a05831228ea200f95382a58d0d8aba36523d9b5cb7506f193131916f3ab66ac9552c26cd0c2ab1c449eaeb8fde752f4f3c3f9b060cc1f8a1e37c4fe5ec306674b66158\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 347706abeb168205cef9b0b8c6b9d6449ac501af7dfbdfbd41a20a6a47872cbd7d4cd32f7b0805ecf1573d534418b7cce98181e079d5061b02639fdf0161cea5314dbbb2ef39ec841f695281f3c7de45f33664e0dd1658f645adc1dd225f781a3fb1634517c556403587b2aecd56dceca9ec19b930cead2b1d303aa056d28bc7\nA = -5e1c869e5dbcc684c245d5c69093bfeaadf388cbf928d33a8ae2148a2b5145937e4f654c5f6a36de1124bad1de8bcc9067fe1f9a44fc6ffe55ce7ed5cd0dbb6337b0e1e96bac1eb2a3606dd97b0bdb975ea59448be50191cc7ea36481ca9fc85c1c3e1c97378dbcd6b355622046888df2ab3d18d805f4d31d464f62a8e630e955beeeb5e00c70242b8f8df708705abbeb95dea3561756298b5f3f7fe16e965294eeeea4546f5e8bacf9d6b4f2136d2e206a87dad1f47\nB = 70225f0cadd328be36ece2172c836405db3fe80ef99ec74fca25406b73a537adf5073f2b550abfc4c0fcc2c2850dace0da9a266768cb4d5ff7fc6c1c248ad74f47592101b61ef96c1302924381abbd96cf49f50c44bf7e0551721a8ae85abdf9925548d13b8c5d1a27be8a40d0f43eec3136bc3035057b75aea779b4262cc66e6bc68da93c218f1920979291105d4b02117d66deb92c3e511aa588b27130202acc9f69521957f79c7e731bbd5461552b9b6b24240dd71ac449be9777\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a2cb238f326d47f95869e2dcb295eba819a443dcc7c2785461389b58327742702f4c86e47af129f1fd4611cda93631f9333c358a29121d58286333083d13e66f30a9533b77ba3e26089e7eff7baf19bef8054af4e24735525908864ea9c4756b42a69c897003cab7b63cfd9a5927ed562e29845308eb2a55e7f8f03c87a5b7ce\nA = -1aa7ae6f56c38b654b281525b9da953ef366c2b9cffd3042105ed428dc7e5f2f2d53ef90b468bb471753606cc7a3775d86bcd2f4d5119cdde3c487cd39bf31752c5ba297e529c1b8121487e0e1de702156d0166ccaf51888a24fe7b48624eefaec855e2200929c21858676ec9bf4ceed0a832b69efd5065af544e49a3d209b85a77b0953652cbf0aa897527c52c9a98de9ae4c827f762e251478c88d410123625ea52b3478b52f6b9987d42009ae427763357ab53195772\nB = -226630b6fcdb5e274a25066ae2ca2c803549dbb935a97c0d7f6ab2c971d74cf6acd265c9d6815a6b2dd23dcb3c23b390fe8b1bed92b8c64c76c0ce62d5e7ddd7ce445bab0ca905dcfd0f128e5f4ffe966f3903d7ff1c61fe174e373cfe35a6d83249ec40b4a354d46fa1c90682efe468e895ea3da710838c262e8a47752dc6e7a79fe20051f51180173b58e0aa37b22eb8efee5b6dc264459ce4d135f430cb15afbf8c53f0de894bd2aca1f7ea32b4209a22a075f7b3b18e86f778a9e47\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9ea62ef634\nA = 55cc58c9d8\nB = 6b49179821\nM = f753311ac9\n\nModMul = e9ab3a2aa60edd30108\nA = 5134a36c2bad180dd5bf\nB = 2ba6485656d041690666\nM = 9b9cc4409e86c8b0fbbf\n\nModMul = 621f9b797e866028b7bd1ff828bf29\nA = a202338dffe171c99434d84f3\nB = fb71eee7045b3e3ab5dd809dd\nM = b3e6e8d53b7249df670e3c59c55d33\n\nModMul = 808d463d06b7b7f98e3cb2783e2196c349d62672\nA = c669426a92d3cb5b316e2b5b9\nB = ccaea3874008dcc92450d8b2f\nM = b04dd2bb325baed1940cd000e8cb2d786009ccd5\n\nModMul = 872164b92b9426b237858c4cdafe1694f96b0e0e4c19e894a0\nA = c3255cb24a813e27c3dc410f0\nB = b144f39e7c2d33605ba7bee16\nM = f3639f4dfb782f3107eb402fabb5fc878903acb5e02e129077\n\nModMul = 6124d7d171\nA = 235b938139\nB = 3a56a22a28\nM = 83eb4af4e5\n\nModMul = 9c006f56095d442ba98c\nA = 207e14237c42e3764e5e\nB = 8a495a26872432fa8e33\nM = d0cf2b8ae5c67d6736b9\n\nModMul = 97387cfaef652932a230c82de59cac\nA = 82ae0fc5e943af5bb8c4adebb\nB = db1279be12d59ba3a9c036a61\nM = aa36dc1d13390169cd54d711eb511b\n\nModMul = 32ee73c98da657464c6fed4274df20b099689e00\nA = 9baf08248ee24bcb17714e420\nB = a7f0428147bfe098666180749\nM = ce0bc198331c9ed1d21f0d498326e8185d3d602d\n\nModMul = a8b3fc0b53df3b92753edecd6fbcc5f4840dad3a44da704e34\nA = b36249e259b303e453757721c\nB = f0c1db50670d92abd93bdc84b\nM = b05cf978bf2dc7e093d7d164e46d547219c480382df32b33d9\n\nModMul = 2663b741ff\nA = 58c8e7f7f6\nB = c84681fc87\nM = e0a50dcb45\n\nModMul = 21af3c0b42328f41b81e\nA = 1f79f5b5bf78c9700d\nB = 5bd1734ba0f0e59c2a25\nM = 9ff3fdfb5c089244f327\n\nModMul = cbc280b5106c2c36cb31ad7e7c986c\nA = cadf6482b769e83ce7f7277dd\nB = f9862a06da1a9c89547b76c61\nM = cc36144c88139ce921d2fd1740bc4b\n\nModMul = 3813f2fabe016e19fd8e70687ff473651a5fbb4b\nA = 9c51a5bacb5d9f055a9ac2962\nB = bfed5625b21b4e82d1f105a0b\nM = a47977acad7c5deeb683ccd265cb30cb193f22a9\n\nModMul = 76ff291a02715fc87ebfb3e99153c04e53358dbd7beae43478\nA = 997c4a7b537d9500d73a205a4\nB = c679ce666af284a459ae5a26e\nM = d0d0fd4922953941acad8beb65c00603b19eb44fb8ca51e3c9\n\nModMul = 1a90c92fdb\nA = 94fa7bb475\nB = 564b0a3339\nM = a1501bdc75\n\nModMul = 5e7ae5470686bad7996a\nA = c725797912c6c5f30d94\nB = 3a7f4c99ee3f5fa9582c\nM = cc50c8b7408f09a74973\n\nModMul = 72a15b13bcd1b63747342a6be8f0f2\nA = c33357af48a2df569e3c11ce6\nB = a4b4c5c14d7796adab54b6cae\nM = e22a0fdca62a37f4c8a61c96a429b9\n\nModMul = 31e179bfbf65b0695dde36a4fb72d131830dcdd6\nA = ce8d3adab8cbf15c332c0b289\nB = 9333f94eeb7d7a86b82becc51\nM = a532a76bd5cff409b580d54d12ef75ad8179b381\n\nModMul = 8f4b8a585415adff3a7bc35fa88891ba31e4a82672c664fb14\nA = 9a2b56a54bd0727ab4be57ff2\nB = edf1781b4296567990773005a\nM = c5a7c3b97ba00d6f174a019c6d37eda52036c528f351bef0f1\n\nModMul = 917bcdb402\nA = 55c7dbd314\nB = 997b29ef79\nM = af5b4cbd0f\n\nModMul = 660c4bb2b771f523a4fd\nA = 43fe52461d5139620a11\nB = 1f8ec4b67de1db54ddda\nM = d0458e215b7e6903d96f\n\nModMul = 7aeff02c143e4426fcbcf32bd1277b\nA = a2671586369a990dde7829f36\nB = c7ff67937c900daccc0ab1d8c\nM = 8ad9c1d4d3cce681d1ae27c27982df\n\nModMul = 4b153d57433f0f7276674d3484e9bd0d25227d07\nA = aea36cf51dd2ce06c66b7a407\nB = 80c9fe5bb0afd2bf8b3644f96\nM = 8cc22a67ed7e5a7a2322aaa09ec2be94998494f9\n\nModMul = 7f8447dd983b113f04c6288f9539e53a2e9cddbca8b2fefcc0\nA = f67636b03821c8f13f21217a5\nB = 8473a29f4ae33f36a0d2c6dc0\nM = b829af37b557c3ddbb5257c8b19144b90708a45a274d6655f5\n\nModMul = 17fe4644a2\nA = 912611576f\nB = 7a10d36b80\nM = c5fa605133\n\nModMul = 8159b23d4fd697b4fd35\nA = be2d646e76494439e60\nB = 60fa770d05ebc69772b2\nM = a6e7c940cd749925a85b\n\nModMul = 7c412dad5c9fff91", + "357bf181caf2bf\nA = 80f476ed5acae75b34ed54c52\nB = fb818e2bdab3b5f4bd84db3d0\nM = d0339f7ee41337d8462d1a9c207d1d\n\nModMul = 70432c749da4ade2c38237545ebfe6c4c6a92f6b\nA = ee9c92de52210e61adaa6eb4a\nB = 8ab55a85b1abab62d33e75fe3\nM = cd3faa6de4cb62fece4c3f94492d457834a6a041\n\nModMul = 9fef1c18778a8691c5e71c0b5208e82778e9bfb632da0b7e28\nA = bd162c90bed25e84dd5b6b77c\nB = d887ee03020c5df356f091db6\nM = a2c2d45fe9decd93a0ca3edab8fee46d27ba23fad9b5294d5f\n\nModMul = 958951bd0f\nA = 12bd0d3375\nB = 668bb65b4e\nM = 9c617dfaad\n\nModMul = 8a109ebc9cbf86613e43\nA = a3e7019f1bbc35689a77\nB = 3189ecd3fd4ffd0229ef\nM = ddadc50600dff2abc1af\n\nModMul = 2b4d9f85a398c852b3a0cc82524619\nA = c244fd157267f707319ba6c6d\nB = 8a07018a748992429bbdbf326\nM = bf3813fb54f749ea5627f59ce30e07\n\nModMul = 28cab7d574e6dc56a6a622f8a7523cbb8dcc5e0f\nA = c9909dcfd3a59a3cfa538b267\nB = 8bbf89cd5a4e24adc2d8c646b\nM = c8f02682b9d480ea98faaca53b747ced33ed0419\n\nModMul = 69b2dfb3f1d8dbb13e9e479f38edcc427d5968acb7751a226a\nA = 8019266c548982a520ab48eff\nB = d33c3e3b13576dcdb3ffaa796\nM = e6255103732475604df7c6f7ef7e6b49a8ef9e2b0c717925a1\n\nModMul = 3eaa4c99fd\nA = 6fc42faa85\nB = dd0b4e318e\nM = fd7f22301b\n\nModMul = 56b6b811ced3433755cb\nA = 145573d17cb0c996c69\nB = 9d3297d5ccc184896822\nM = dcfb3b383506239e83e1\n\nModMul = 34315b6bc6d3690c28060485ae331f\nA = b963a26973894cfb42fcb2d22\nB = e8523304bbcdff1a0ed4141bb\nM = d7a379aeac7d8cf94f19e7924d35d1\n\nModMul = 2ec9466e8b3357496f07e37ba24d36a237883846\nA = a75f3904e564997695b6707eb\nB = f9f47bd779834dc1f5fba0654\nM = b3ae5abed45d09c4dc5abcadc3ac9abebe1949ed\n\nModMul = 88b4d86b2c1e1bd780e8d2499c2221e05fab4f9b7047c2a044\nA = a38eceb9c551f0e69a544072c\nB = d5f8e7c2d534b2b8985bfd213\nM = ff81809b84fb8eed3508ad891d3d8208249d8a902a12d6acf7\n\nModMul = 172f2e2e22\nA = 1584ff1055\nB = 2e0aee014d\nM = b904cb0bc9\n\nModMul = 122c10d3200270b9eaa1\nA = 86fd189e62a6dc1e4ba0\nB = 5235635f7b0336f5f235\nM = c93da97d0e95fb63dc4d\n\nModMul = 3e461e10ac4eb749512097fbf76616\nA = cf4ce10cbca07164f3812f89c\nB = b7e4639c233fbb0f923fb5104\nM = 949647857e1406871593fad5c30101\n\nModMul = 88117b59d9fed79dd6aaf083ee938215a995a221\nA = 94c888795567d434123d441a7\nB = c60ca79e61a352e34e0f78bee\nM = d2553a7c5dccd639a3927697a2e1af03845f2f25\n\nModMul = bc5f0076a8c2f6cc8f4e61540d2d6f6d6b13b775b363dcd71c\nA = c170eaddca5295d6ec6272dc2\nB = f94a5685ced7661df2efbd34e\nM = fa6bc46aa05033af72aa42793e9174af2e3ba38992f33572fd\n\nModMul = 1110cdbe5b\nA = 5db02b38f3\nB = 3369537903\nM = a8863f7979\n\nModMul = 90fcc5f3a346d3d4ea4c\nA = b93373680ea0feeb31d8\nB = 37f9dfaf0e180be64bd5\nM = d595cc29237d1c19e2db\n\nModMul = 8623a9997e514cf3c1d06c33c14053\nA = b396f5ede6212f1fdfc7e7b77\nB = 81a1ddc18306f2d2e84030148\nM = a6be32a91b34857842255ef8b1aafd\n\nModMul = 63f8f0254df06356f5cab8941b77619ad58025ed\nA = 806b2627b08d987438f920bae\nB = 83297039f4aa8efc1a185fea3\nM = bb8a7e7c19be02c25cf5682a0eee655fcd5b69a5\n\nModMul = 697238dbe3d395e81f20c9fcc8db30c234a1f75f3b2bc27438\nA = 930b04224bc097ac1d8bae8be\nB = b79496a80e45212c4663e5b64\nM = 8ff7e19d967d317c255380411898d73e3786269f09079f19f1\n\nModMul = cd93b5b8b1\nA = 47a51b2d5a\nB = 86d6ba5155\nM = efb0ad3643\n\nModMul = 2037821ea789118bde0a\nA = a92215dcae19be637ff\nB = 93b9a3664a406737958f\nM = 9df360b69ed26f610253\n\nModMul = 3bf11785d28ceb668dc55b870faf7b\nA = bc8758854dc48e057cb6210de\nB = f03ca689620a77ecd8a6f0de3\nM = f3ff0747d6e5f34a0ba4200f579259\n\nModMul = 7b30b44f75ed12f54136858ce4fe77d00e0952cf\nA = 993cd09f3e46423a8ba2053df\nB = feabee384158032dd013dc08d\nM = cd0b21388cb2033b1e792ec4078334df70b6c8f9\n\nModMul = 8ce1e17972f1a9d2e9437d0c5219354728a5f31337808d7650\nA = 90e5d18b017118177ffb080da\nB = f8e7e09032574f6c66e623ec8\nM = da795e6ef63ff7dc4baef5c327022ccf65d44e3c4e24823f11\n\nModMul = 8fcd412054\nA = 2e7f9b1a\nB = 6283de2c9a\nM = 9bff560ae7\n\nModMul = 57d0d3b79f1e2f3632fc\nA = 2f8cc403de5af54cfa39\nB = 3b798c3ead52878dfb2f\nM = 805e6cbde400d4b4bc9b\n\nModMul = 23331614e88633af879201f568c359\nA = f21f19da4b20980979a645dac\nB = ea752050b79883dcd69222536\nM = aed3faf4c88f7c4afe257c5ed90599\n\nModMul = 56dcf9ae1c787e773774df3c8762babb4675a212\nA = 9accf901fa599da05fa6ab5ff\nB = f7f6b9b1d7bae06237532e39f\nM = b5bcd776bb2eb0805ade3c8b47e883962d3cbdf5\n\nModMul = 61d0ee0786963906a028a1df01f836841ab6d39d88ca2717c0\nA = 8e57680f213d088ff1a1e7db3\nB = afebecc9943b0093f87022940\nM = b6201f68a45265d7e9183c3255feb4c110c05dadbcb13881bb\n\nModMul = 143ae78a29\nA = 334abb952a\nB = 74203e7a50\nM = c9535a9505\n\nModMul = 897a2b57e69f5a1469ea\nA = 1ec8ca0ea4fed52bdbbf\nB = 3a6273cab05e478a57b8\nM = dcb33163a8ea42c1ae6d\n\nModMul = 4a2c10e90e2d37111db79a44d3e31b\nA = a90e7bbd63fc4af6de83029ee\nB = cf09c3dd50b41afc7045e057b\nM = 8ab85d47e4270116a64f97dc4f0f15\n\nModMul = 70f94276c9d85fd3f71edfaad6051456f754da85\nA = fa3e9ff6e1aa1fb78e51711cb\nB = b115ed197c50b7ec4040ca255\nM = ad63f69ef1346e7549ba71c13b24b279f53bc9bd\n\nModMul = 861e7ef401866f815b983ba18a612913ecc20a67016d79cfac\nA = fc41a9ce06e882942f751be7a\nB = 881c05a51d1ba8134d126a48e\nM = b12200b39526c33b70e8aa23ebc400dea0d4d8fe42be103d5f\n\nModMul = 4e0051898a\nA = 2a06523f70\nB = 651b5044f0\nM = 9da4eb09b5\n\nModMul = cc8274c88d6affc3742f\nA = 9ccf0133f9628532f4f6\nB = c1d80907057be7a67b01\nM = d6e76e362da831f32685\n\nModMul = 568f15bed5c4405be9dd04673a9c46\nA = dd6029c3196feb6da7f0f4a48\nB = a5f6745f2cb64913d1d3236d8\nM = f62f02c9b9ca8993e3be9a02b444bf\n\nModMul = a629452d5ed19df040eca26eaca37d82c0fb1d8f\nA = 963c51a9415b03e85ccb09f25\nB = b1cffe333afe44311cb968ffe\nM = ab2128698d498e8d75455033cfbbf4487535773f\n\nModMul = 814030123025d287aaa8b826792999d72f2d589e0c7f7f3dbf\nA = c3b33f391e78bee97ceddf313\nB = a9136f3af450fdeb245eff425\nM = b6aa9c517eaecb70781e597b907583bbb569e970d229235a35\n\nModMul = 8735bd486d\nA = 563e15c52a\nB = 31293264e1\nM = 92f4b193df\n\nModMul = a541f69ca163b288dd0e\nA = a608b48c1dcaa18424b2\nB = 891b0b296e911068b00c\nM = d4140921f4b2c84f1eb1\n\nModMul = adc1b7cf65967b013d046866b4ed9d\nA = e97941448f65060cf63ecd486\nB = ca68936f76cb87a8fbdd37311\nM = ebbca2482fb82eeca2866057cf1179\n\nModMul = 44aa9f0dd58d4510a7364e130698b34eda23a632\nA = c11f83f01bb964ffac93a2e30\nB = e05ee40eea39f4538d735193d\nM = b5e8b511738979dc740a6a1f7291cf4561787be7\n\nModMul = 8b16b82f064f471983c7154abc9f9ba355111bacb90400372a\nA = acff8da571e1c96810bf95707\nB = cdd23e5504cc26d0c34a62b06\nM = f38902a99190ae0b5ef26849a6e943d651925666fea271fee7\n\nModMul = 193f453197\nA = 8cb3078675\nB = a8fb003a87\nM = b60ff22f4b\n\nModMul = 849c26c8cf5cae426a80\nA = 5d1e3d2b4d038a0a34be\nB = 34f70325565bf0523314\nM = cbc189f9a732cad8f425\n\nModMul = 9a4e64ff530c53a4c6c5b6b5021920\nA = f53b81723cf74f520a61e614e\nB = 9d8ac2e6b839143fdd079a2ff\nM = a115375435151798f3644bede9d863\n\nModMul = aac303a4623e80158af1cb3331965cc8e3184edd\nA = cce0a88606ff962fdc37e72c9\nB = 9840a500a2051625c517104db\nM = b99dafdbd91ec3c05791031df5e193c03d6a441d\n\nModMul = a31401dfa761bbe82b66b5f094151865b18a4ba75bb9b3dedf\nA = e6f48c027284856aaf3b96425\nB = b4c326f72a6a22fd4b93ba5b3\nM = e57d9608ac6e5b129b2c014958bfc59137f63838b1ba88a4ab\n\nModMul = 8b0929adbf\nA = 61fdf77ac0\nB = 8892f05400\nM = f12b3766eb\n\nModMul = 91b57f353307b173679d\nA = 33f8e73752072b4b5cfa\nB = b4c730f79f4f2c07945d\nM = d41be1d8d2e5753e3ae9\n\nModMul = af04c564adfeb120bc4770bc8c650c\nA = af151333b3d4cd1d29fd801db\nB = 9ccaac44ff91be11b30bdcdd0\nM = e0bd6e70d5f5ce08fbbfd48d43101f\n\nModMul = 1b8d623796a5065d9e993a53a9587a0fdbea1bbd\nA = a2fd08df2d4eab0cd6d29e213\nB = 92c9d26ae7c215b52199ee28b\nM = cd529f4cfa46f3bd3e7fadf167fdc02f6f881da3\n\nModMul = 4a8573dd8dc50a4fa39f3579d3869745eb8c1153ca508deefd\nA = 855f941d085305725da617f5d\nB = 8f09b7d2c36e0340523da5421\nM = fd8caa05edeaa81beefa01957eed97a981ab34bdeb6d8c704b\n\nModMul = 2d278e089\nA = 59d20a1716\nB = 8e2a58bc75\nM = b3d61ef699\n\nModMul = 2f937ce359d0f6cedd1\nA = 1019d11d26040ffd5b1d\nB = 7cdb6252087423d43e08\nM = e8f537323004447e669f\n\nModMul = 6567332e25af83089f7458786ab0ca\nA = bf9565e9f8a098894447b58fb\nB = fc867626f268c24cc0ab7bf8b\nM = 930f39183353363dcd822933a438ef\n\nModMul = 3692e73ad1d91ddc19cad3808eba2c5fc88e2bf9\nA = d0a42ce512629f0ffd233a9aa\nB = 97f6d3c4c655c7353a62d6ac4\nM = eac2ea84851f880214b8f40f881a2e56a6ba6f2d\n\nModMul = 81df390c9e51b30bd639db15adb464c7cb1d011cb5e260be58\nA = c237eb242c40960861c938c08\nB = ab2f481f0d768eebd90d2574b\nM = 8697d7a28a5f42c9a7b31949b8b568f861142f44fe66c6cd3f\n\nModMul = c952f9aef\nA = 81973bbcb3\nB = 28ddee3bf7\nM = c4a40993c9\n\nModMul = 2", + "41dd53d93f7bdbbb2ee\nA = 2136eda4495c45c9f96c\nB = e74c4baa8ca3f6b7cd5b\nM = fff4594e7a5f0a1d3e15\n\nModMul = 5f861ed8b0aa835761613e6c869cfd\nA = bfc5c1572086079f5f5d18d1b\nB = 95902e14923c8010b7e905178\nM = a819c6c109d623f9b845aa23712c9b\n\nModMul = 5b8ab089c4e4c6804e48a2bc1d218718b3a32598\nA = fbe65d3852224a812c432672a\nB = d57a3f38da966d2471d70a048\nM = b9e6a626d3ad026d14248fc90c882bedd64a1f13\n\nModMul = 761438baf5b02dc095b7040e082da7b167c2b9ace956284ed\nA = fd91701ed2151f8e994bf4ee1\nB = 88b66e735b76972bccd9db182\nM = 8008b2d1274456aa68dc627b1ec3e1762c6ed2d660c64a1a55\n\nModMul = cb743c97a1\nA = 9c69ca9b60\nB = 7488f48f5\nM = d67040ed0d\n\nModMul = 931b2bee1bc30725a31\nA = 650f567b544ce02303d4\nB = 5858da30dd1fae88a675\nM = 91ce30234bb29fb9e833\n\nModMul = 5b4f262cec958a20390b5e568ccdaf\nA = f7e240e8a077e8e87506db2f1\nB = f8653fe64e3bd414782f51634\nM = fdb8225eefc1620648737d31dfe1f7\n\nModMul = 4c011d1ddfa30c901793cc6ce74db47584cebbd1\nA = eda8e9a9ea3cdae17bd50b1b4\nB = 992e8ef4a45593e4ceff67876\nM = 95e2f120cfcefbada1058af6c8853cbebedd5763\n\nModMul = 6e99aa5b8107399848cf24fbd88ed6350efb68d737e505b466\nA = ca6c51ba2f410d09bf71d60fe\nB = 8bdfa8fe5ef3b2ad02bc63c4d\nM = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb\n\nModMul = 536175913582e73c1002083cb0cfce5471d4193a5b717881e60abfe927c829d\nA = 9b474b6f7d7f11dfbeb7a0724694f2daf9ccbaf2ec13269b5ae3329e8df95f7833baa68324509dcddfb5afa1d14f2dafc55e2c225475f16fb396beecc7a66dee\nB = d74a5081f00af2361c3537642c06cd47aae7e366741c9b4785e185af8b328acf3e2ed71e3b9a4b6fd49d956eef76740b3c6ec5850a90e7e444dfeaa7214c5eca\nM = 5efaeebe212752b28b5441a5d0b2600190504467c6359e9ab26320ee72cffcb\n\nModMul = 6161cceee2b74e7965a926fdf5344ddf8cc41994d72154a8b6014c18cf71634\nA = e7d6b74a1af0834aaf93e09a6488340b661449ba2bbc73d775e7d828163813ddbcd82719351879a6d67ab6b518011e1db43a3d620d1f24403917691d15ed6f90\nB = 3ecc8fd3103fe52a7e73ec4be4e60b69584bd886a030f017b482bde9d4b0b964ba8471cb32b3e9bd49864d9028a22d6b6b46be0451bb4222c3987b74a509f8fc\nM = 7c3e3b8b1a6110da82674aaf88c288cef4cfddf22e7c9b75640fd67fa5fad59\n\nModMul = 2acd55bdcccd55882eff0bb262bb62f78bff8e932aefc9d32f54d5d4e9b8bd76\nA = c221d1f0d1b7efe7e078dd01bed773f8876fa324b3fe91985d47d343e7f3878b457dae2f9ae68971245278a1d23cb541c56b94dd9ac43a9fbe28a46efc627651\nB = 49f94c19ff7ce990637c3d2019ed66f7e6dbb1442b04a4593cc480521b991cb1b878f8c31903240f89e34336d9e6785433617e729b71adcbef622a683357e035\nM = 43760c71742e9cf22cae6fc262c008b7f1b97a78c8063957b74aa4cd370c1eeb\n\nModMul = 504c11e38284a30e3647c1ddfaed94503d833bcecdff05e749422ad1d9442540\nA = 3fbabe2d65f443e7db0a6f332330ecc4d1d40e14fcb510499552020405cafcf10a50a5ee47cf60fd8c22a22b3f753b4167c213851f32109babe4b5c298d6c4cf\nB = 62e5b0f887dcb1f1794bae7dad46a066f810cf5f82a1eea99207b5f0fb0ae9084c5e62cc97b2672b1cf4cc1400a19bdcb093c97404876b584a6482931e7ba9b7\nM = d79fab3eb31189268b2a0689cafdaa0826f07d432591e8aa8bd3c7cdce1470a7\n\nModMul = 13a6431c57ddf0ed3979412ba8454a0dd9a2694a0dd76453aae63366c46e41db\nA = 7e1fd0bd9ab0aa75b264475604aea09f24239f94847ce2549d43b71890c0549938d167adebc7890d3c492b5874da7bf18d895ccaf1803b9776820598928b407c\nB = 5e54e5185bc86f16177f1354a57d36ac2980def141b389e4bfda134fae7c158009ccc61ef66281905128b6297f876662104ead2315024f129c56eaa387f80b4d\nM = 182572149b860615dd853f37f7d51a35e85f5e4a4249a60fde58dc68e0dd7401\n\nModMul = 145a44566bd75103083b7556a822ea6008ed3a6a1bf135b68fcf87a294c09b4\nA = a195e4315caa8cc0707063c7359c28139d4dfffb57eb726156336e13227ad9766ea1fc99152893ebb194fecfc153d47cb927a633217328f05e4d8782aeb89d04\nB = a97ae97dc7e9a224cab94ecedc08d0cbf7a012dc5209b1e1e8b5b843fcf61e65db3457d6085545a633be47b742e8237cc716357ff5bce9b00e23671ec1d049a8\nM = 29b060ee2aef7e43e02163d279ce49259127198adf462d13aa195c7dccf573a1\n\nModMul = b00740cef7791692d45f5a7110f3eeb260638f19f87c9245436fc0422de90658\nA = e6b97c11ad44fd451d168d65d1691d2220db8c3b6c8436d59f4c1366aac52558d0d6b61f5d6966460a4a31085fac711e5a09af5563d938963555d4730982eb0\nB = 6805eab5a4da534f07def6d2c320a6cbdfe4831fc2163dfcef740607b3181d8647bfae8f8c16237c1c1c5d14b9e3417132f81b3a7db4b7fc11927aab30dca590\nM = f975a94fa62b4c0e68df5c3ac5917d18927c0a6d9cf39c26f6ed97a81cedf227\n\nModMul = dc04b6ba2eb1e34ea8942a50d1d0c5479dd22109895796ffdc9cd32b53d4764\nA = 7fd3310af09a67e0684dcd8e3b4b651c7c13c2f6a0a47b59a7f5cd8bd80854d1d4fe02eaa61843d6bb2b87f99d8ec4842864681eaf056538ffff610c231e1d\nB = 15f1661c59ee9f93400073e18a91503a93d47537d2da5cf5e4bc69ccc87b07bed171a95f1c5eaa9c7d7ab207ab3f1f7634c5d16e706969e869364207f61d84bf\nM = 22e2856f4c2b6c01448d4aef74aaaee3a14e9660b5b277200f2e67464ecadfab\n\nModMul = 19299c9e960ce15087e9fbd66f95cafe82546431b92d70db1de87c3425c1bef2\nA = 8e3abb1f24e1f91496db99be9409f57f67cfb6e0e33d603a2a31e1309f1d0bbdc413c3e4fbb5e3d923f683afa9942b9b9fad6a6e558b2297889fff47ccef7d23\nB = dbdf5940dcd68127d476badbd5a2f3018aa4d8db79f81337ddfcb108637110b934e946d3284ec09d5255605ad72424f1894238ee4f7964dffc27fad838532321\nM = ab6b4e3d3909512f5d1d62a30c1ab8dd5e584cadbce9dffd12fe203f8936ee93\n\nModMul = 4f88ad4e30e6e8e38cba0452d98d4a3547c680f16308692e33e5577772658764\nA = 5137697bf48982edd869e4a42f3cb858bf65ad5b25d1c0e8b75d054460d0944ecb5a6924721c5728964d84231c7ae808f556837aefb23fe3ad36aec9f5f60f20\nB = c79554304620f8116b9a8bb56f6a23620e9fd504f7163f732e1e6367d25c6ff98cb01d16faf3e018dec6a067d1204a6aa95470598ce757bcfbc3ab4f5d8ec88\nM = 9ba20dd78923d8ef82897ac46a509cf22c9b7986a4facf42e5416bfe3576a735\n\nModMul = 985a4d2a7431e09fcad03e6a3f926582dbc0aedc588f17aa5db40c2d3566233\nA = 908bff40440aaeee6c90b6312dc017c3bdae884a9074e02b26f01be1f018390e01f0d111f99a06c16e20538df8000d4066cd4bb3628da88a3a5cc240cfac719f\nB = 6ebfe9fe53909876784f9d6e5dcca4cfa9463fbd8426c5bb8890ae84c2fad119615fe1e1f2ee5fa544a5ac713ed1da8c1e04f282f1f1b9fba4b4c4bd9db20538\nM = c66842e0a11ed6ad1e8f192ea97f5f244536cfc5234c7fdae1ff905123c72793\n\nModMul = 133d7b31537b627da2c042217cd28625437c28c3e06258427d9a4384046a1f4\nA = afb695e3e40347f60a500e01fba4df1c1f2fd4ed79e3f65913d82369f79d80db6b3978e6351c70c148f572b9c0c2b1efeefa605251b3156d9b66d240467e550f\nB = 8855046dcf50f80f278227d5260b9be53ca2e4a1cfe1afce4d35b11d0fa17a36a8bee8126e13bbb318d476becad5a935e9d160fa481e1437b292bdc169dc7d45\nM = 3eae4f0d6c7e1fb9de1a4c160404a8767783c7f839fe27a543f5c389c679d47\n\nModMul = 7f4576a315bad5c7fbb1616e8b26c5b34ca6f701b9b1adf0485fec181c41dee9\nA = bc2baf0153a4598f6b5f488c43b2546cadfaca2c1931b919f98ba71835a8fe78886da1fea25b194e60ed6f9e0ad23c988b64af9278155c1722dcf4983a1566c2\nB = d8374d91fd3c523ecdd6bdd265c9a8958dd222f9f0e25454fd683bd86d7900a273b56f1f47e033c46527e32c721094ce6bc927d25fac05d7fa6db4d7a6773c94\nM = 9975d8e7f2a4d9d1ff8d442b93ff269a83fee43a18bbfa8c2ccd7ca5fac3a8d3\n\nModMul = 57ebfb39605d4fa6ef5fd03bd8e4fd685664297c29b7ad75a40b133e15fc5ae9\nA = efed8e442154b1eb6c75775cc23e01fa65c9c361e222da123d07daad3039f305e7102edff23b65c333f0caae4f7929857c3169f4ae47c9f0fd920c38eb42bf2f\nB = db05415ea90269a74b0919ff772c148c0eeb2ff9dea76a6e73e82eb86bc76fb42308b55ef83a769a91d23b7840d5d2f5129f15279dfab7cd8d63778acf202f26\nM = 7704390c4b1da86d51ff817003e5451d601a5352296e339e5da219ec5a330479\n\nModMul = 40b6b0d44cf8a5ca7f4fd03dd6e1e2a11f74f3911dcd8727e57db8d65cd490d\nA = 6500f3cf686eec4e1f243616ac0ea8e8d11ddbade490b86baf231e7b2fd55968ee14b6bb7badf8c898874099831976af46bcbfbfaea10d49aa803c6e51238e2\nB = 1fac744fa1e26e789639e049679d0e2eb57336279f09555e10210e7143199a3df5fbf5294edc386ac762fa3a3b0b4bc28945adf21a8af747a29018bf76d3710a\nM = 5c0781a87b84ecb4362b09c623d511de53c085671dd4f08e9a551685b55ddfd1\n\nModMul = 6b778ae9822221e6a8376379e0032d7edb14d7b5e32a7310897b54d1d5626113\nA = c4a5737a9496129a136753f8c2e52bbd2660f2d3fafe4ed702900b01c14e506d13e3bbeab19b357e5ba9fce8a4fc3dcc469406a16248d6fb53862781fd9d55e4\nB = 444e5a673eeb37fd3b4f6b6f5133b0f46c2ea532e1953da4a0e144407a8e2534c5ff40cc9af7756e5aff9df57d938fcedaffb868dcf4e458b36f506ed7fe0ce5\nM = 7f5978c0c066132a9bdcb00727bb802b72777b9e8e4265f76b80cfdc3a788817\n\nModMul = 5c717e5dd25abe60f761d6f9326ed056416add4c1384682d87b7ff12e112f855\nA = 4351965a421c75c5b4c251861e53316a300ed7983e27e17f9308420f0d2cb11e9c476294fcd9042a525bc1a044bb442d1d9f853c9e07245170e0e2711010cd1c\nB = 4e1046647c362c8f9c414be54075b4e9d151c6fa0c3da40d90e6042625947ca2c9f20cfbcfdab8666dac5a15f6cda9d47b09f654131fc5addc07e382c9639323\nM = a6c789884c66c7f028099e0367b3ed86871277bf070c541ee12fc02fcb6181d7\n\nModMul = 4452688244f542125168853f1d4", + "44f96ab0f82903bb12a97e59f0db633edfd6\nA = 9fd1cc81981bff977244c044146918057ad06d3cc26edfb8fb4118ee02b959d45555f9507ffeb23c3688e29ccdfe5f583fa3761f6727573542bee8ab5f5b600d\nB = 856e6a03b5c93fc19deea51b3bfe42c810c5bcf9ffbd08e2625eb209baf6a4e24943a3c090d89c1f70aea9f0128e511fe92e03715d917168c1e1ca77a3a8731f\nM = 2c245d407a78903ef2b279ddbe32106e6333b6f44cabf87b8641b047c79ea06b\n\nModMul = 375f8474ee47df6b9a038512002e56cddd374d69c69719d8d369232c64a839e2\nA = add40f1dd6d4a2414b17f0c628eed9a8f082f3ad1f34ec41935fa86b34d4505b22ea80c062386a9ed63f95c67e55c686f837bddf8f4da791f98b08c02f32d4b2\nB = dab1caaa11d5a208b7a6b7a1d6482a4859daaba5e3a77b1b1020e8ae62a664953dfddd0b47d40526e7a3c6a5363c6d41dd9f529fd8b58d5d31bb67e745cb71b3\nM = 4f506313a4f49873a405f2e5a6e9cfae9cd5e9f67b5ef900153366570e28a955\n\nModMul = 36fb0733a26902f0f8f11625305a3c94fcdfffe294eb6ccba110aa628a314df\nA = 52ee1498bd6a1677db801ae2eab4951345a1fcf8fe7d38e3f28dbc27fae508d87c9958e02a375ff4891b88ee916b96331e7cc082615faa028f6d541b5ce37876\nB = 9343cfa074f50c20e8472f8f7c4a7d330aa30ee417ed8027a4c956e84cc5cb31d5411c14796d9325fceef79a51b5d8a4c89182ca273ab633e6a7b22a27352300\nM = 9d7c334aa33634f9f313b71b42476a3b627a6c5bb8ac1d07a8d732d5c087bd9\n\nModMul = 4a377267508eb045e00cea66a417112dac07545304bbeac6315625275b7cbfad\nA = 19616a82b75b08499d4b1f869df2db8f71398672f3f97ffc6177a4a5aa913605ce8a6ab5f778cac508f0b3f2aa680b01ccdc57c0fdd6cd678a2ff2dcd7f01f3c\nB = a5643a9a9fe3be4134082daae4ee7dfd85d9452beee856fd939d3be9788b6bebcf3571c67ec481ff9b20f70d23e82e2171b1d0ddf0a9435b40115d32aedb6811\nM = ea0477e7f1a02cb6c21171066f3dab69d4e24429043b0f049de660fc80e51937\n\nModMul = 7952dfdb91252658430e365adeefd9093740de92cfc9dd3d92294f2dab6ca0b6\nA = 8e6cd7639b7c134b53e6ae6ac5f51268da83ed09e8e96d65e4bb130dcdbbab9e48226ddba6efe93faa510bde8ee92f2a641774c4272b5a2f88024b77a2cfa110\nB = fe4e8109a49b16b96871e384564cc096277dad4e1bbca8e5feb33f140a4fb800c8f3096b1bc7042bccf249aede88e6055c0db609f94e214b1251eda494be724b\nM = aa46853682af960824140c35d145a6dcff6283b2c59994b30ecf9b8def41a025\n\nModMul = 1aacec7f7e66b0cf4eb2dfda9d8d3fbf4eb8e928cbbc967d13e3e38612f0346d\nA = b0fd7a936b0908ba6fa797e4b855d673ff85d665ef3a345e560e2c0049becf5c25b6c0068dd617ab47a8fd151939ea0631f86806ddd40e557933c0e880fcdd0b\nB = 105c87fe2b1bf0be5405ca0d530beda1780f0045e892d7810f8a8abbe890f0a19de66497cba55bf38e190c52992467c22a320c38a4bd167f774ed812f1271d5a\nM = ac4f0a2b22df691331ded955a5d0e7d1910d7920a59d4a87636b2635397b7335\n\nModMul = 2c25d180156fa7d2fc20c9bd6d9ff0b111c9ad76ada0784e2f8fa0bd06413f66\nA = 2aa4a0a73df11f4e60956619d0b35eaef45730d619f9b920298e6d369b9861f6411de28a34af038f288d7a3d6a35b10c8082b8ad0fb275a8f67c6832ac46ba9\nB = fae1d50b72feb25da2581829409391bf289cd9f730c99d265b5b2d63889381cde4adbf85c3998c2478f2866526b8f64605d75765edd09b78ea45337207d173\nM = 65c9d79a09a820adbc9beb152bef387c1439147ed50cef872d36a69f1c7d5fe1\n\nModMul = 56ec8624fc199e7b4e68358f88f1a99f1d4d02577b8c6f7e28e4ccfdd981f995\nA = b0a0f9d05d144d2ef257c1e63a7127a3b8e0d8b64ff8f6447618560593574b5c5da6258b274efc28da0defd988bef1efca0f481f809665a78954b36741d668bd\nB = 10901b9dbf0016cbcc671da75a75b7a6ec6a66dd17b53a97344864b08f037098537380bfb0137b6becfc36a75206686d16bc4eb8fd54299494374e3f383d9b10\nM = 73882376ca850c125ce9f20c291e550ee48f0eb0d571109ab08c22d6719496e9\n\nModMul = acceebe131aa34ff21b3235f045bccc8a8f762dca20c1dd1ef6eb461ea971c6c\nA = a7714b249eb0f0cbe3e6fa0b04e895fcf14c404876197defafc6b57026ae7e5e993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b\nB = b7278ecd154ef5243ad973ead291ea186acb63e09977e644a6a9fde195d1a33993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b\nM = c52ae49e1a4b21ec392b76844ad559653b7b9f67a58b3bba6c2ce250017eab09\n\nModMul = 62b5b04dc84bb4ee04934c03ef361bc6e59b42144dc117b9f7771525c67c3688\nA = 2b65f491caf0b5cd9c66c859fbcadaec7213e6b848884638791b1620d6e4bc9dde087af0e7329d3b15a45df2d43ebde61b053ad7f63917aa922d58b4f3222620\nB = c1bfcdb34b0766be980540dc3256b9ee4158310fad2c43cf24bfafca08ee185647043f5842a9d9eda224449259341b7c50998086434528d47661bf5762a7ab5f\nM = f73398c32191b436d14a0b76c6069b1d61395568753c832dd0c707780a232dc9\n\nModMul = 5613c8fb0721bd3f605089def48fb2c38a4862bb387886c1edc1bc37d10f0e15\nA = a3d8b12a2c8f4021ca045a4e4903687dea63ee7e88893b1911aea77efbff00f8f5c7884cbafc71f59fa2636195c2ebee61edbf642923f34d87ba5eb49b06a7ee\nB = 3231829c81b26dcac432b502ce22e126ab564922b1e9818cd3da46edc5ce7df026d0e515809c97bcfdb9666581efbfd364437ba9959dfad099f90472f97c69ec\nM = df8344fa848d1066afe4f8d985cff65441751677dcf3a4e99b40365fc3c978e9\n\nModMul = 30325f7ccbc2c69e11d739ad7132a947c53377aa902ec70b152f3a75e050c244\nA = e4ba620125f58a63fe12fbd3eccdea477d56b120c76d5d1421bebd74e8686b4093f8169070453ccc04b63b173568385313a1d9c841a4aa82a61cb84d4286a941\nB = e87aaa990307855f8e5f2e5509d2ce31dd4b13bb7199cf5fa0593e350326e222efc33a26c69245565d6ebb5a484cfef7d2558f22dea8054d07831d536803d0dd\nM = 43d57108eb0ab9bebaa8ce137628ea825951c6accb9acb7f1e991c93b8563897\n\nModMul = 1975db7b72434ad32c9aee412645f6670b7f4af1f8a424a5031c559d3e18dce6\nA = bd64b1db27fa7da4c92a4ee092f58a2a53ed0f12d009fe13b36d5fd585defe778fafea4a60e8fe567d03e9ba3b72b189e22504ae8ca6aad7c2ac0f44abca2f6\nB = b487d8116198560d6c5b08c7ce63b0acc0c98e6f2a8d709cf4e3a409edd55f64d72fc27a70dc341e280ff5a1b09fe131773d466cb31991d2db23a2a86d225c80\nM = 39d57af763eabe569dac1a103e169e6e3b4375168e41e5c3b961b6e743915923\n\nModMul = 3bbb5bde9e3e240694326571360090e1fc0a4ea7b2311c1e0bd3961f6c159385\nA = 4181ee3bf9a98bcd49eaea243a179cddbf160981efc720685c7be1dfeb5aa552685a2cd46f340e1e1da893b3b460692fa2eaf6c100f24a14f239e45123242d53\nB = 77cd04d86dd5da322af78be54246dd6b7af490d903db1db03cbccde535570b81c6053a84110c07f097540ffe7510320024b7bafb77e9e239761def76092e1d59\nM = f3b9833a303eb540cf8b6cbc3cf16394b1634ef517be57684e42d364d8bec3e5\n\nModMul = 2d8174211f0367233b3a8df7c5bf0066d6aa792be7cdc5e850a477454d5c829f\nA = 1c08cec52d96136fbd9078b7b8db36ab63b86e19dd3dba7b2e3190ff566180e89dfee9423fa4e99be2187eda6aedfa86b9a45eb1e4655257315ae6a280f0a6ee\nB = a8b4bc9647d8df9b7c76cc6d0f2248cdbc41f5da9c061f9864aa8415c9557582cada456cf23cc32d47d1fc1caf19d36b398019aac4734e10f55ce3cad419e5e7\nM = 7eacffe21f88413af94155a2a8e37f70a431a59653738afda04a1bec72d0d9ed\n\n# Regression tests for CVE-2016-7055.\n\nModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9\nA = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nB = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81\nM = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf\n\nModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9\nA = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81\nB = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nM = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d495", + "4425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf\n\n\n# ModSquare tests.\n#\n# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M.\n\n# Regression test for CVE-2017-3732.\nModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff\n\n# Regression test for CVE-2017-3736.\nModSquare = fe06fe0b06160c09\nA = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff00fcfdfc\n# A in Montgomery form is fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8ffeadbcfc4dae7fff908e92820306b9544d954000000006c000000000000000000000000000000000000000000000000000000000000000000ff030202fffff8ffebdbcfc4dae7fff908e92820306b9544d954000000006c000000ff0302030000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fc00ff02ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00fcfdfcffffffffff000000000000000000ff0302030000000000ffffffffffffffffff00fcfdfdff030202ff00000000ffffffffffffffffff00fcfdfcffffffffff\nM = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffffffff\n\n\n# ModExp tests.\n#\n# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.\n\nModExp = 00\nA = -01\nE = 01\nM = 01\n\nModExp = 01\nA = -02\nE = 01\nM = 03\n\nModExp = 01\nA = -01\nE = 02\nM = 03\n\nModExp = 01\nA = -02\nE = 02\nM = 03\n\nModExp = 00\nA = -03\nE = 02\nM = 03\n\nModExp = 02\nA = -04\nE = 01\nM = 03\n\nModExp = 01\nA = -04\nE = 02\nM = 03\n\n# Regression test for carry propagation bug in sqr8x_reduction.\nModExp = 19324b647d967d644b3219\nA = 050505050505\nE = 02\nM = 414141414141414141414127414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\nModExp = 208f8aa0\nA = 86b49\nE = 2\nM = 30d26ecb\n\nModExp = 27308229\nA = 17591bb\nE = 6\nM = 30d26ecb\n\nModExp = 2bdf498f\nA = 21292626\nE = d\nM = 30d26ecb\n\nModExp = 11317167\nA = 4a655df24\nE = 10\nM = 30d26ecb\n\nModExp = 2e1b88e\nA = da6b761a86\nE = 35\nM = 30d26ecb\n\nModExp = 20a12ec3\nA = ea811\nE = 2\nM = 23bc042f\n\nModExp = c42ced\nA = 1011a6a\nE = 4\nM = 23bc042f\n\nModExp = 4637d79\nA = 28d9a601\nE = 8\nM = 23bc042f\n\nModExp = 20e5669b\nA = 72fe6bc20\nE = 11\nM = 23bc042f\n\nModExp = 142ab9e3\nA = 9a07b9363c\nE = 29\nM = 23bc042f\n\nModExp = 14c64646\nA = 822df\nE = 3\nM = 30915765\n\nModExp = 160e35a2\nA = 15ea542\nE = 5\nM = 30915765\n\nModExp = 2f23a488\nA = 34d2e02e\nE = e\nM = 30915765\n\nModExp = 28e67f93\nA = 636a32703\nE = 14\nM = 30915765\n\nModExp = 29bfeaa5\nA = c8646998e6\nE = 2c\nM = 30915765\n\nModExp = 30959e22\nA = 81dad\nE = 3\nM = 326dd68d\n\nModExp = 1a1da4fa\nA = 116adb9\nE = 5\nM = 326dd68d\n\nModExp = 272bf0d8\nA = 2d21ef08\nE = 8\nM = 326dd68d\n\nModExp = 29f5054b\nA = 76989850a\nE = 16\nM = 326dd68d\n\nModExp = e6c7b77\nA = b88ee70d2a\nE = 3e\nM = 326dd68d\n\nModExp = 369605e1\nA = cf26f\nE = 2\nM = 3ce082eb\n\nModExp = 168a3c5d\nA = 1f82caf\nE = 5\nM = 3ce082eb\n\nModExp = 125c4bb8\nA = 2e9c4c07\nE = 9\nM = 3ce082eb\n\nModExp = 1c5fe761\nA = 523ab37f1\nE = 14\nM = 3ce082eb\n\nModExp = 21703009\nA = dc832165e8\nE = 20\nM = 3ce082eb\n\nModExp = 1228d1e\nA = a5555\nE = 3\nM = 24665b27\n\nModExp = 5226af4\nA = 1077bd6\nE = 4\nM = 24665b27\n\nModExp = 1b14eac1\nA = 2db3a834\nE = f\nM = 24665b27\n\nModExp = 161727bc\nA = 6bd962cb6\nE = 19\nM = 24665b27\n\nModExp = 10d61d0d\nA = c10caed407\nE = 28\nM = 24665b27\n\nModExp = 233da406\nA = b125f\nE = 3\nM = 33509981\n\nModExp = 24032799\nA = 1656b7c\nE = 6\nM = 33509981\n\nModExp = 129ecebe\nA = 2e671504\nE = a\nM = 33509981\n\nModExp = 20c20bac\nA = 4d7a2de44\nE = 1f\nM = 33509981\n\nModExp = 2e3ce9d3\nA = c53b3def4d\nE = 31\nM = 33509981\n\nModExp = 12fadfd6\nA = b4cf8\nE = 2\nM = 36e9d4ae\n\nModExp = 457ac85\nA = 1b1c7e9\nE = 7\nM = 36e9d4ae\n\nModExp = 31debef4\nA = 3a973028\nE = d\nM = 36e9d4ae\n\nModExp = 2333ad93\nA = 552b97c45\nE = 11\nM = 36e9d4ae\n\nModExp = 99ba1fb\nA = 8bfb949cbb\nE = 28\nM = 36e9d4ae\n\nModExp = 27b691de\nA = 93492\nE = 3\nM = 298fdb16\n\nModExp = 3c2b70f\nA = ", + "14e7b0d\nE = 4\nM = 298fdb16\n\nModExp = 1486cda7\nA = 29acff81\nE = c\nM = 298fdb16\n\nModExp = 11725275\nA = 507489205\nE = 13\nM = 298fdb16\n\nModExp = 24d14627\nA = e71c55606d\nE = 35\nM = 298fdb16\n\nModExp = 222b8d14\nA = 9b1a0\nE = 3\nM = 3db59d12\n\nModExp = 3b8bd47d\nA = 13f4e8d\nE = 7\nM = 3db59d12\n\nModExp = 17e72356\nA = 334774ce\nE = a\nM = 3db59d12\n\nModExp = 306447ca\nA = 47079ddd2\nE = 12\nM = 3db59d12\n\nModExp = 90bef3b\nA = a75d62616d\nE = 37\nM = 3db59d12\n\nModExp = 1\nA = cddd44f47e84b3276cc36a5c0d742cc703e61c4756168601fbb1b6eb598c161019562344dd56ab6f603d920a12c360b285e6496a3605a2f8d691c3598233ee9366b5f2692554893bdeb67b7bdaf35ab7273ac593145e26bed82c70ba5793bf4bc5cac4c80b01785d1496beede493806e4f4aa89fd8d41de80dd6d0a3e2742678\nE = 0\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 0\nA = 0\nE = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 5150fb769d5c5d341aaf56639a7bcc77c415fe46439938a2190283409692f29cd080bfe3433005d98d24718a03a3553c8560c5e9c8ed0f53b8945eb18290e1c1a83d919302510f66dd89b58acc2de79ad54b8a30d3e1019d4d222556beefca0821b094ecf104b5e4cfce69d2d520d2abf54f3e393d25ed3d27e8c2e3ca2e5ff9\nA = ead8c5a451541c50cab74de530c89376d9a55c723e0cac3c84b25f0093c08a2961e49ab48966361c42c9f99111587252d98395b76788400d75c66ef208ea2767a28d6f8dc3a859f39c95765d57f139e7fc14f47c908c62df051e7216d379f52028843b4d82ef49133cce8fe671ae179423ac8da5be43b01caaf425cd969300cd\nE = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 1\nA = 935561297d1d90255aef891e2e30aa09935409de3d4a5abc340ac9a9b7dce33e9f5ce407f3a67ec30e0dc30481070823f8542463e46828d9cafb672a506d6753688cbad3d2761079f770c726c0b957071a30876c4d448e884b647833befbcd6b582787bf769d63cf55e68c7b869a0b86374f8920516cf5d528f348b6057450a1\nE = 0\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = 0\nA = 0\nE = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = bbad67352704a6321809f742826bf3d1c31c0ad057bf81432abeb30dc9913c896c03e69eb1cde6b78ffcb320c4625bd38ef23a08d6c64dc86aec951b72d74b097e209ce63092959894614e3865a6153ec0ff6fda639e44071a33763f6b18edc1c22094c3f844f04a86d414c4cb618e9812991c61289360c7ba60f190f75038d0\nA = 855144760f2be2f2038d8ff628f03a902ae2e07736f2695ec980f84a1781665ab65e2b4e53d31856f431a32fd58d8a7727acee54cc54a62161b035c0293714ca294e2161ea4a48660bf084b885f504ad23ea338030460310bd19186be9030ab5136f09fe6a9223962bce385aaaf9c39fe6ed6d005fa96163fe15cdfa08fc914d\nE = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = 1\nA = 9d92629c1ab181c50c31619e8acd0d235a1f5fc7a0bef4d4fd54b4f1968d45921f8522efe88e69c6c14c576c564592b9feb00d1554b88b038934eaf4a8ce81a2582732387490181ef158360c8b2d9ccb326ffe043f776a50cb8202837f08ca743b562eefa007150ab7012c341b16248478d4775c02ad71ea13d5e82b71e2d600\nE = 0\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 0\nA = 0\nE = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 24eaead5b57883c2f454928f8edd470a344bfe07a953194f7d635d705ef13ddfc64140c8ad6f363d4c828e7c7891a6b6d4df37335de4552c319dafd1c06d1f743240082a3535df4da1475d3eea3fead20e40815fd5a0876c881c162ab65a1eda494280c258901ca953d1d039a998bf0e9aa09273bbef4865f3054663b72d75ff\nA = a31618b4532f53729ba22efb2221432fab1dbb70853d6a1159b42fd19fc949965c709b209de106a652aa422d88922ce51dae47f7f6deaf0055202e13db79ee84fc3d3c6f4c003ef96597c49d6895fa53c22ac9e4819f7048146b5272f6279424fdb389819a0b251c823c76f4bebf4f1246de455aafe82a0d34454f5039e90839\nE = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 1\nA = a8558e7f455b27c0c46d7d0862eb409cdefbeca945e0284b5bf425b7ac0f3d316bc365594cc1639decffc621214d61479bc75135120d4ac09ea8b742ad7ec1822091b62b1c6f564fe5e2f4f5b7def92cbaaa9a898549207ab01b91c2324fbd306a87f7d6379b6fb6493c5fca76729767f136120da9c90bdc7d364f7d242d5acc\nE = 0\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 0\nA = 0\nE = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 292f0b39ca0f1c850b1a00cffd2d54924fcd5fc7e7504c9d593e6c0ff74760b1f4bdd81679fe06c50248336f3108c593fa111072ee87d0fcc89a63243a1dc89044503663eee9bc18f51c3e0193d9108303e12ac90ff78f6ec752a4386af09c42db524a7cbe9a3d4fcccd56c34d283bcc9debc17158b5fe8df0c1888a9841bf8f\nA = b4fde290874", + "5ff92cc5826a27dcfdda09e8fffee681844fa4c7f1354d946d5d84e0e0c7a4a4cb20943d9c73dd707ca47d796945d6f6b55933b615e2c522f5dfc33e0652917b4809bab86f4fa56b32b746c177764895492d0a6a699812b2827fe701d40ef7effd78ea8efe1cac15ff74a295a09614bf04cae1a5017872ba22efe\nE = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 1\nA = e2845c572b46496ac158a731f612fd40ef626fa7134755c25b1b7614f4d7b29164e6142ddb7985e4c7ebc575855ff901e95927fe98a5aea2ad3a4720c75782323bea1518b2c57790f44efd9411be4e95b3896bad1e73c59658290b309e5a7eb5ef8be08125063e57336b80f17eacee88966d12bbaaa15a25929c82e027cf696f\nE = 0\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = 0\nA = 0\nE = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = c90e4c69df92e26549b016950b59080947f5403430698e128477782480dd70be96bed2b9042dd8c708eb432e02710555b97af11ce6fa9b53395022851c32d1f53f04237fb0763563b440ca6e81a50d909d907d9c26b7d3c420dbf88f7dadd488666848135f8cdc608dcfb0691989289fb54379c2e84c262f9765f68c012ca1b9\nA = 882ea1b9b6c79a3b1bdfd284658cb6227ad825e0178cab713c7413c2ec34f03cfaec470c4f5c521f5e9899a2123878ff0f5b36a4196c08ad1b04d03746c4bfb5d126f5eefbfe172627d6732710a8ac8890cedbd4fdef69a19f2b3253a5aa0e5dd5484f72d59b17bdd1dad3db209a3ab839368ed3975069685911d7b35e41a9e6\nE = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = 1\nA = d7a99e65b8af86b1c51d851f0447e43cd4f343cb0ada7236283e69aa7ebd383826acc9809e5dbc4002d0f2430022cb026458189db3805ce2de1142a31ba71a6c064ab51f0059eb4b931b8bcbaef023c38d57aa5f3e14f5df77e547fc028702071b58bd57338be1e1e4f98d3553484e4de359cefa29c5f58d3fa5d823f389dbef\nE = 0\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 0\nA = 0\nE = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 186c50ae259aa0fd31859cbcfea534e626a254de33956d5d719334bb32e7cf37cf199a21f079a5b90497228994d05efe19ccd8c769cd81f896286e8ae557cacd1630a928c629ecdfece29ab3697794aa707734e007318fa7029b050bb09ebbe6986187c6ca843f55266d275620b3f0fec0ad5f847ce8b314d929d128b33a249e\nA = 9d5e345793faddca9867f23eeddf6816c1e837f7a2cf96fa077212514acb6be87ac01a237d8f2f1d07d27a8ddd1b0ae0d97e1bda4f205a89435017284cdedea3e407b1b940d6f52112b6359b3e86e4c83074b17c210ae2c8856b42b169b4a7a6dfa65b368a7959496cf9bb1ee93d019dbd79101830e3f5ed08604ab90890b914\nE = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 1\nA = e6a079bdf7b0638d50b183475e9ddfd5cbdebfb29f5fae8e9be402a0bd36085737b556492ea7fb4b1000ae9ce59db66098129b757cfb29224275fdaa46b8b7eb18a93ca7d3e446dc38c734b683d7ba7927b008d993aab01f44239d3c76be76d1503908e9b5e73b36c43ae0771368b01f39c042693bd92c4fc50810f059e1b332\nE = 0\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 0\nA = 0\nE = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 60719701a2dc0bcde281a93ce0b8421d1a718adee43c1b5d9fe9e697a48ab3db4f9f33c73cff305ab6b6c300c149b05c6b289dce4580860dc56bc59de81ac074ecebdc65aa3ca040b44e5b3c80ddba1658d78b9abbc4c77e5f171f5582e70ab4438a8e1e2f062d618c4ad09c70c73b5b5fbc9f8f0bbdf1d530a933b705f85af8\nA = e1b400cd3b1f2f1c6b437adfdb970d2c8108f1b39bdbb13582179552011c6c97cba6bff2c463212b7f62776aa3e3aff9f175990e79395e819c144350b0a23d61638d500ecc97726b098e1af334aece23a851c718612442c04eb7b3805a24cc8f5b90042145eb5e5d6a408092832b6bbeb8a621419a9282fb5c075f41c7f1fdc1\nE = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 1\nA = 9dd1e6f2d3ff24096b54e0ebf0f10e283e484a1cbafc0431adda1296ed97692f3ba99440fd4f67c96dd8bab850e1123361c99362df9ea205ff8e90d1b329459f54730992d5a360e46fcc5f5a909e691abb9a06613d6991bd7c2aa609f0d7b441d7ded0c07b8c394327672d38a905efb2d76aa3be5bb14d0c002aa37e287aee79\nE = 0\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 0\nA = 0\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb9172", + "51919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 86fb0b8dc161c41de2adb0f3ddcc8ad49c1efd729a52793a3ac987d4011c9c1dadb18657dca718df75c8ddcc49d60f152c46ab85ae9076ee7bfd405679a7da3a5195a1bbfd7d2b998c7b135ea91f8c445cbafe1276fa502c2a85477716829a2e0d24ba02623405a3654bed8f355bc7ccdb67c3f9a01e249e358b60d7699498a9\nA = 816610e6018ca47074d55750dd16a281019dbf95dc752605794cbb8ea8d75775317ce685737859728320b529fb3b4414b40bf3a93d08d8994a21ae54682cc1c357eb529837a7b0129a0843eebd9341c9bee3a8ae30475bdbff517e885a0c9f2b6a680643bd981efb53bf9dd49f3dc3cb757e117895fb34b1b4336d9bf8384558\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 1\nA = 9edfce4691f46eadaa2043c7b1092b831ed50f3429f0bca02f985c0b77c686d951be84d772ae4b55f08935bed6e3206c8441574f215736b5c1c1b7595b3b789b55cf56db83741b10144d6767ba2b97b23a5e83504c60e06ab22834b0145655aa0463108317a379cbfc8a93de8a66925a999b8b02bf88dd85fb9898cefe9c95c8\nE = 0\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 0\nA = 0\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 442866609915aa6f1bae9dfb59e721e1b63f42c0f75fbf0a88344120fbbd7aacf15208fb7c9d8bb8477d553cbd826d7e685ad764a8423e81c2131c040ee83a03cab8d5ce50866a941b48c78e9f1330794d908562d4141cfbf26e8c80c69551339eec41e37e2b37b54330f7bd75748f8d26d56ab9eb3b0c127540484c6445a7fa\nA = 8ff65e2cbcbcd8697cc3ce9a26855d6422ac7eb4e66500648c08be697e005cc3c854a54cfab91d43489cd60be8b516a9b3c9688e5e009a1689c6b164a133859a5464ef422c86344fef42cc477c9df27768377c126a066d1b62f593b7f6d6e906feaee16addb7cfbfc043d741b7dc81a87c17f167b7b8ef1b1fb3dfd1eb14102d\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 1\nA = fe9f77f7d0475e00ec964c0effb9b8e079c32e376ce77a9c40ce4018c3df44a77b4f294d9565502b2b79accb30cb58dda6d15e1543b6d4a53296543ed11c7f51baab60283ef03fae37dfeacb431392487ec2839551a933895c4dbf18844f7b375d3e6f558d3c39993cea1bbf7fb743a6a07bd3753c03eb7298811476d7f3ff1d\nE = 0\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 0\nA = 0\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 91fd879d02f95a9f40fcd1037726f73892caf84e9b43b4aa4126d9062a0d22c464e7af2fbd91aa849612d99d9519b724a7fb1cb018fffdcff321d883ab2519953c9f174f09dd8f13ac87339887385966eb4a94842276637b2c36c0a5036b1d3bbea438bc6efd4b4851c7ec06879d60694df894717569bcd31c4b13d80df6cbca\nA = cdec5edc1cb3ea974342b85aabc0f9385cf877ca328747d40dd4d297623ad69ab6582653faeed5aef225208305135cfbee32e066cb43e18afacea3a32acc8aabbc49617ac33e741651924ae56dd6aa044a12a1ea50fef573b5befb2f4b21b9cf83ab2aaa6fd153580a0761666ade8fb94f202a3c3dc4f33297eabb4564374168\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\n# Craft inputs whose Montgomery representation is 1, i.e., shorter than M, in\n# order to test the const time precomputation scattering/gathering.\n\nModExp = 9442d2eca2905ad796383947b14ddfcc341f5be8fec079135c36f6f0d9b8b2212f43e08bf29c46167ff0fe16b247cd365df4417d96cc31c94db1cf44b73b0ee3ebcc4920d9b0d003b68e49c1df91e61bc7758a8a1d2d6192ff4e1590b1a792f8be3a1b83db3ad9667d14398d873faf5d885ec3a2bef955026fae6dbf64daea2b\nA = 3a4b4c57e62c5e9d1a9065191f8268fed9d5f6f424d071acef66f0662b8210f4c029ed991512e40c9c912043c816d2c4c5b53fa0e5c253e16808aad4225130dafbbb89fd4f30cdfc1c2f2179b636a7ddc4be579795820b4b9377637bd8a21a0ef5a90d0e0f865321eee23d9be2a3b7320b4012d02941b892df2c40bdc85c1898\nE = a2c56ea1362511cac0301918e15a9afe7d37edd438a5c3538d258ea01f0a6df758de07111e868b3ad8fc89b629b4955d78a1b3af902be1806410ddde25ccc6a196ba5949395c1ad5d8725b18815dc1cd5ac1c7dd17773f571e3f2e628255af14476e0494be23a4a4dfd18e23142f33d7a59c236fec61660e360d9676a747c69f\nM = ede35a3a7afac817d413373a2032abbc067b1493f709ae6e1282ee5469743391d891b904938857168802b7872d3cd7ac18ab249a9e540a86f970b1d0f310a4cc29df1cc9d4063d98c554f1a32f4ca5eba3523cdfb142e0fc609907c7a92bb0187009d97ec471db3545f42dd5fd29c07b7816085d09477ba31fcf90084660116d\n\nModExp = a7f5844fa9e7202d4b70ee252c9846e63d3d091b0387768ded872cec53458e19df0d9b4960226e269b8ca5dd4c4eda423a67b6dbb48235c08c12c6c7c78db47287756d3ed9cecb9232f7d18d5d80b9676cb68ba4a290c97e220beb1a069976b5e6022a4c1e5ddbeec86b62dda24ffea1deda37695c9f61a8817218e6370c0679\nA = 7d6d0cc947ceb949cdc4e9e1044f5deca5bb05a491041e0d85bc4b92a0944a57c72845fad91e59010c61ad1712bd2f612d53a846a044632262a9f2e3373b062fde2484e0c165ff947f2469f743ab6e2e5e13c640fc4029b1c9213eb8473c674e7f9e95a4a5c5636d4656c1e696962340d77b322daba47d6fc894f2a2cd9e0afc\nE = b78012afe806e2344d004c739c97324256850980ac97d88c4ed9a838517639ca112e235978d21a176c33f5a68703aba0f2a05501bbe3fc8d49a000fbf530cdb431581dfaf8683cb15a2aee5e239cbc542827100da3b47babf4a16ca7c588aff9912e674abb449e0b767a15e415f4e7f2bbd6380d7131da3df8d49b13bfd35ce3\nM = b72d5c55bd2998472f1965e75a51be6155c1ba04656da8f66bcb34db36a7b1db66a89d1d05b1bde10206acf85be7b474ab689220faf1bb52ab39d8dc00512dd4e26df1179c11b973e1274db85a88c7cc2a17113abdffe58cb930ddc5f3ccc4d68b4e65c913730509f7ce5656e8bbaba9b1be177ab9f766678f018fea05da9cdf\n\nModExp = 465ff295786a88496828fdc763e9292d557957544e9322b7996807b87fdbfa7a11614bffeec557ca831c4824c8e4ca3b1a1c7f3f4f95ec3fd6a86b73bb13d78b73af2b3c7e76954d0cc03bcb0cd606867ebb3765a8b3d0108cbe4f343a14016be9c33f6d200f0dc547e7d6b02bfab1e79dcdf9c9835a814cc6c855a12ebeb66d\nA = 89ad02bea3e9ab839a6e23f20122409daba52c68e1e893034b30d321c0305434a6af940015e3fa5ca9c35230da34beeb1ed4fbce6c1da3a8bfe3f3ae172276c1d1723b47ee61e6f8fcfdafad102d6f7ee2a79f510c7edb93096205a40a6c9e665b88b18f39a979e2e61286d939952a6f02fe8148b7515bb25f4252337cb6e60d\nE = cbd6ac628cc7afa3c61bee9c22a06a395087ec1811fe9681b55216700", + "c435996c815e7cec8aaa90016dd2382d0306a5414630124e14f3d396a4ba02ee17851bf720f1607ff813e4bbddf01338983db12f59bd6371a738eee3eeb716f21051d6174d2d6c77602942b9edaac18d4b3a723096c0d00dd23a8a605c585022f311560\nM = fa7a3e40364c8a8d0f14f0213a3f3e035222ca0ea19d46d10ba41580e5dd2805c8a133f3856d7d5d97f922ea540e5eb0d10ad04dfdbb74f518f58da0099a6fc2b3f3def92985176e07fc78aff2faebccca10a429794e5f15ff92f75fe90f527c60ddea8093a9078c703c372ca09f7aeb27ade02f3595308c61dd9c44e62fd101\n\nModExp = cf08bf00261402102e9fe03f3074471dcf0e9b3c96d4d1503f099f24ec85e1901b023e9e048c1ad042244f5f70b38b25a99f4c0a7b57d5844bb0d0137367f45f4ce2cc7746105b77414768cb97648dc5721149aed2d4c682408cc0d50d26dd0bd77e848911f8625c727cac5f32e63bcb548f41a57d718d772f23983a42f603bd\nA = a419646a6631c2c69b18f7aa65011825eb31692eecaee9d74f92d92203811b68e9764bda31a1585bdf69b6273fc6f9f508c395ac081336506525dad88473512f08a205621ac8b16e9864c7a7c5a4f17435de00d0b32badec6ce4897e3e1076c562b6d9523f63d0b2079eaa416cb090471657763f24931d955d1fa2720c80a9c9\nE = d5a6f4a1842aaee39805356dc8d0d678ee03b2c81277345beccb2742f899132feb43271f95968a01ae68aa8277201851992dc0aa7a71c90aae71b124d873ee264ea400fb131be0fc6c4ce8c04c45f6bdaca89ac743635caf6158983d257e21cef6800d7f990e912ba21bbfb8fb779afa4abd19e07e7e07eee9908493d1ca502c\nM = e739689b6cc6def1d45fb1a2ab551643beeb303f4aaa4da47ee5e4948510f8445b4c40e99ae8354dede60b2ba6694e93bc4d573b7e8adf871b7a9a9636eb7d70f2e49328e2d7978143b177cee8374ef01bd1ee2d95862765883f5e7971668b53ef0ff41b6539faf63c397522b0bdce916388e72e26c8d3d2e58dadeb9eb5d479\n\nModExp = 827e6312ec3b14600203bb83f5b277ded197b2967363630ef673240df05edd3ba8ab2b11c86251a612206569c6c33952b31e264f129909bfe723bd0ee1624b36cfcfaa893a6ec8b5a1f7de79f83e79b459a3350f89f412ad1cfd6bc4c2a7a29272c783d6ecceeb1398fa17041835643f4debef9b5e87b098d104bb8912dddf7c\nA = b8e49c637829021d32db3a39a0c1e58cdd4c6e4eda7e8e9293be379e9c2e2d184f929d278598a81ae231cfedcf69cce4a6e31cda3c8ac14d753a7311f2436e29795f0dfb60259a0f61a997918ff984aa2284b43a9d64c974059e9682adfffd018305835f74eda8c75fe4877d811c1620f654ec9f7f32d1af5ce59115e2f41785\nE = 80e0febf369d234bf1aaad4f82df2e2ff02882c3184781f6ccdf4f7cd93b6887af86830077c84dfb02109ada05b40970b1c65228b0c19030bd6361c3537fee22a8155c03b4e7007ca006c6daa3659518d05bb81ea0079456d0ef6116df248dffdb0c935f321f5a1034deefd5a9414a0652aa6548de33325b474b9e5a8507a082\nM = d5eb1d14af842a9973274f7463d90cf0ccff19c47d710edbae184478d4f29b02693ed7958bd487054327b9e6d8879e24c9af7730b92f323eeac05558da6c1b952e5dbf13de236050a77628bb5325fe0d14cc5773bf73338759d5ab43c212b414581280f1cee250007e53791b800b61c90de0328acd7bc43fbdda48158939392d\n\nModExp = 4a1efd29c7e78549f5cd4deed1454b37462c7810ee6a8a2493b764dfa479be13b314cf9ff98259517d61865567ef499a511630c0038c97914625df181c6fe07892f329f98b344a78d751e9471483eebaa7977371bf97bb25187ae7e93a9227d6c124ccb4644423c961a11ae59c4354f89d5a95164c23d9aa256e289e9cc0858e\nA = bd86c9211fa6a47a06e5016c46cb8a99e34a043a29e22f8c3196fa7197c26b38927b8d9bc0ddc11a5fa4bcc44deb69dbf37cbe7ebc9a2fad6c74e09ab5a9dd929fa04ab4319b6caad1035739be78ba631fb0748d9e53944836d37ccda6e6a62823c696d8f31139ccd7f2f86b22fa026ecf433cfb1271a3539ac4f1c83aaac059\nE = c40b9972006d28a84c2769a86e526a2b274f73afc7c5c6a2742166757f61b5f5fdbb228afa157af62af989ffe966f232bba9e6beef5403d1690ade31a6410f7f349a35bc4267a129afd647993df7d45cc0e1a1ba4678d7f1b6e8a344d8ff7037679e1f4db25a454e4246f6b55c416567fcfa188e8a3865115851d9edf0aa8902\nM = cf424d7af75ce7eef90cad75ae55ca8810cc7b4703fdb5bce701e7bac07e0c371cae06df2aa8facb55a0faa6793e4d2bd9d7969703743b9be170be82792aeea55e2bc0f7ab7617b276486bf474dee2f4556aab595ff3ef115139cfe5e21ccd4ee05c0e1cf901bd85df86cc17195a783b0be836d00bee82ce064077f9191188f9\n\nModExp = 3137a3049fd4ad2e26d870f5c998cf11bfe82101884a82e85e43facd0928cd7434a2e346ca124619769fa141bbe92ad6f36b99231032ddaec3b349a410f82b5ca36f45e56e5fb85dc63d32053dc90805d3f1854ab385281a71a57726bf97158494e7476057214ca7379ab8b70f5bdc15f70bdad3adf33c3a1f9cd1b6bbbad556\nA = 39a1dc6a4c3f14d9c350ee968d5ce139ef725952c967a2d1bedf48ace22091283525be03807e2e263d2640be77f0525247bcd07149bba50568cec5a082c87d72962cf9e43bcb5cdb1e7e9a650fb53e0ec2fad37f09a9f036c0d7dfa528fef846769f80a9a60854910ca1b4ee05dba82ed2ee018348d6b3e52a764b8ffae61e0\nE = deaee3a3f80c9f684ed7110c0653847ccc7be5ff6d982fd4b49f59b5dd35f7210b1077babbcedbc127df35cd469dc6e569a0f84e58149b5605c94b09fd7f0b098d02b4a04631328b3fae39e6c2fce25334225cab71829abdb9507cb903701559660f2c08c3b743336119d1260a0db27054cad3f28bc1b04b2289baa58fb33965\nM = 938388927d06ed3bb1286c0f06d3054cb0ee16dc7a0bbbf13a45293c09a5f40f1d611b2e1a1b0ec2ef109b508e27af4274954905cae52034f8740a744153b4d22059f0dd262ea51785522098ecacced6da07709ee6b5acc8c4e99331379a7c3de7f4e2d1431e43b19570140955b7bcba118dfbaa552cbfa2be531e8f781166ed\n\nModExp = c15ae334455d9f4d1030cd33e734726a27c63624c2afc576238cce5e0498298a4a0c93090a0d19568b41290303c4b558f3d9dd74f9cde8798710f68569ea0d6fd971ce67ec5b54495031de3d8842b8b49288725bee5c9f72b99054d64986ccd4e18d70d5f33943f08cd694eff538f84438ea993ebaba0910c95b3a694f213510\nA = def633b955a917569df3ba8517455eef0655e7a35985edda27097a063e0d82c7c3a76dc36c5d8a71ba9d540790ddd0ea514aaed98925f9a1808eb288d387aaf9605a9ef8a333ebee7ad7057bca012efd619d5867f02266f65976ef4b16da17468426ac4f99b3e8921707e01b4de20f6f9a068e6a19d872079a27f3a44449db83\nE = a465c47b0d15d48e01bb8b1d8e3b3253e11515f6874dbed6c25818adf1a8fd927124d5593beb367f685c11e46f18415be73ccdf16fa2e93a600b728163d21d232849e5278c3749d903edad3f1c4535a2f55a2ab65e7ebc64888bd2a0527e876ecf38cec3ab1980d08138709fad8eb88ae65d960adc3f0f8e92f784fe96fcb693\nM = e43cb9ac1446154356cdc31ec771c79b0e461e22d95185bbe1a279c0945e3af07903a0cb54d553380716fcdcafb4b7cf5dc6da481dc74a8c583d75ff6c1f8e429182d200246ebc473bb56e173787987c1b7fb2dd23f5b2e438a97bc4a1df628bc044fdd1e80c0cf37030adb7b04784dab827d0dcd64f0dbf37c980612570ce11\n\nModExp = 75c3f79ab7c991b98e65505342a8a563cfb08b5d3ccf8664c7db1de50256b1d17ebf7096dc98c7bb5d7f027a894ae5cbb14dee04d5d445e775ad7e239acc82673b0ac2d819a69c83864f34e73d9a636f05de8279619a067b4c90ad038db5910447e03841d2034635018f08cbcd21efa00994247763a249082594128112f95232\nA = 34def7d76f6f158a359fd12759fb889cdf6af0a24830dc3e84283a1ab4e9b2647a6a36b86482f829b2cdf3e3d6028f9a884b1f64f7262315446bea8b0231828e2f3d990fb103c17f820b39e4b8427c85643ceeca8f5dc8f191d1255768300e859bd7d88c770319ef38269660d221cb3bc061389b6fc0783485ef042b1c7d6fef\nE = c6c46453dd5aac6b37277a446b1d0c69cbe476eeff55b3ac35edb89ba97116b0e7783660f2c7b31b2a2d6c4709d0ab45d01a838100694b0777c9c9c14c959b07c437c73a5eabb7402f1001e802d797a2e7707285834fb6440a1c2f727f7bb84ddb2a49312d32fa0ce620c43872655cb5c394749c9e75d7fa25be00efe50d47d6\nM = fbbab6698a9142095c46b38a732592e4366c1838b84bf40f8c8fc7b630f73380a0d09765562365798f8c8030ed1b6728329d8bb06e882c35a1d59bfe84146a9db2afe42a414014e247390281c782fce806d62adb54778d2bcb49555459429d6ed446af5359657667f6aa19e8e3e0e24ab2bc312b2d90b5cb1ce6f2f15af15d9d\n\nModExp = ba16d7f3f6e162ce248490d164a13c00e7720d8a667e2d3ebeb13f1663e15ef5408d5b56cbc7bc793a8ca787cc50f8e15e0e9d4ee764531d04a9114eea556bb3e206ed7d85267151a056b6e68fbf35e03f2cf829708ffe1de13e95ecfe365aff1eea36340ffcd3892dee659fb1ecbe50f5080e54737c10f9c1ba638b14ef537e\nA = 9025e6183706105e948b1b0edf922f9011b9e11887d70adb00b26f272b9e76a38f3099084d9cccf12d04b1a99c0f654f8b9ed90c6dff9478c60bf05d58d734ab60eaefa14a22230ec60c90dc1f0704b61eef0bef345785ae0e6a9af7db069cf6bd2b4e0fe58a0ade83c7e46a04b9fe1d24cb9b65c6f80de713e61d70eae5b286\nE = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae159400943725570726cdc92b3ea94f9f206729516fdda83e31d815b0c7720e7598a91d992273e3bd8ac413b441d8f1dfe5aa7c3bf3ef573adc38292676217467731e6cf440a59611b8110af88d3e62f60209b513b01fbb69a097458ad02096b5e38f0\nM = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7\n\n\n# RSAZ 512-bit.\n#\n# These are regression tests for code which historically reached the RSAZ-512\n# code. That has since been removed, but the test vectors remain. Note that the\n# lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 7f34c1cd63377bc3abf2", + "bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4\nA = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same as above except A is negative.\nModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd\nA = -8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25\nA = -80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n\n# RSAZ 1024-bit.\n# Note that the lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7\nA = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# Same as above except A is negative.\nModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10\nA = -21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nA = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa", + "42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d\nA = -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Regression test for CVE-2017-3738.\nModExp = d360792bd8210786607817c3dda64cc38c8d0f25569597cb1f363c7919a0c3587baff01a2283edaeb04fc288ac0ab3f279b2a89ffcb452d8bdf72422a9f9780f4aa702dc964cf033149d3a339883062cab8564aebdbfac0bf68985e522c6fe545b346044690c525ca85d3f4eb3e3c25cdf541545afc84a309e9b1d7807003461\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020df\nE = 2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020FF2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020ff\n\n\n# Exp tests.\n#\n# These test vectors satisfy A ^ E = Exp.\n\nExp = aa6d7ac431\nA = d0e07\nE = 2\n\nExp = 12d416b110dbb4e467ff0c89a22122f4da8240\nA = 1a18cf6\nE = 6\n\nExp = 49a3b33e23d84f1ce0d5d83f5dcb651d50cf3920f0143da2310d0512a90a06cd8f38977df8a756c30883de38df092000\nA = 2a3acbd2\nE = d\n\nExp = 5b4a0d5a956f885f275712b194459980f24708bfb6393d71bd37dce852ce455724f5ee5030775fb86b4295edc98afaafc097e4d82a97c0078ec0eac763db16549c5145c4cf2d3124f88cf9a5c71da0625afb99b26801786fe49a778415dc025954021753d08691947a208b613f0be5c1\nA = 54b3ae461\nE = 1a\n\nExp = a0ea5f6a4de49beb8fb7f0dab280d6a32c5a3814c9a5153a7944cec0a9028497846a8a89044348721a0bb5f0c3ded3e980574ea321b0cdb0ead4f4e93841ea7478a7f15d9729b646a8165813a0750e8124f5465dda9b105e1bbeff18fd09c09a2e26610d9176d253b877c3a8908a6be521cbe1e472a7a1b7820e4e890f8f28aacd34609c686e76e15b01bd9324a71290812724ea564d11c874a6765b262c3e57d479da0287a76026a1e8fe53da0b02405da1d379eaa30fc65f\nA = fccec0f6df\nE = 25\n\n\n# ModSqrt tests.\n#\n# These test vectors satisfy ModSqrt * ModSqrt = A (mod P) with P a prime.\n# ModSqrt is in [0, (P-1)/2].\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 5\n\nModSqrt = 1\nA = -4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 2\nA = 4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 2\nA = 4\nP = 7\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 4\nA = 10\nP = b\n\nModSqrt = 0\nA = 0\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 2\nA = 4\nP = b\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 3\nA = 9\nP = d\n\nModSqrt = 8\nA = d\nP = 11\n\nModSqrt = 6\nA = df\nP = 11\n\nModSqrt = 4\nA = 10\nP = 11\n\nModSqrt = 5\nA = 90\nP = 11\n\nModSqrt = 3\nA = 80\nP = 11\n\nModSqrt = 9\nA = -e\nP = 13\n\nModSqrt = 7\nA = 7d\nP = 13\n\nModSqrt = 6\nA = 37\nP = 13\n\nModSqrt = 1\nA = 1\nP = 13\n\nModSqrt = 8\nA = 1a\nP = 13\n\nModSqrt = 54d4cf0fafe265056a29016778cea6b712bc66a132fb5e6b6865e9b49e4c97ec\nA = 599c10484b22d0b5a115268c7538ca99b3253a311a4ab1ca11c3665b0bec393a1167d1ad94fb84cb2c7ad7e2c933e8f613bdd08fe1f1aa4a9b0b9de0c8a7c9d4\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 38a7365a15365e911286c1be2a7afe76ef390234d76269e04dee17313f6ea54d\nA = 1c4aabb4d8369710131c664ecf2849e963c1bc31d66e0b939bacf99a870c71f24ed71bdddcf566f3908271fee43fc1ebb51eac7e3153efae641b49d2e796a12a\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 35ab18a560dece04725667f640ca61d1d59f14d191f94c79f58531acd097d444\nA = 685168ae855d60eba220d803f5296459b30a289580668db9ed51bca51cc2d453a937e13819ae34f7a9a143ac96d17420c53919167e46279b562b550be1cd9abc\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 288370029e87024175e5bec0eab0929179f42e16995e7f6194eefc61061e54f4\nA = 2a14ab77c045bdc48220ba9c463e1a4b4049cb01edb53be0937767eb2ec19b7d719855052281250a36a0b76d9a5d967d0756e1ded7a052f7056191ad66bcfc9\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 32255cf01dc943577ec2bcb221b98491d7a1130d046d6c68e95fedff643ce3a4\nA = e26f6dd46a513a1dd3fb14b71be1d4c9e9d79eda1cde10ea4d1eb8abfd4d5857572205e247184dd0cbefa37b5c0bf680ba2bd28c5741f725cfe2aae37419baf\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 5172345e801ada63fbc4782e32583cc3b4fea88b9e6dfd542f3542f8538ade66\nA = 40dafa8342b302bb04b1f3ddb3b9015a8fc1b597857c115b40631c7be9e22de89358fca23b331596ee5ff304dad7811e6d8e8822f7aa533c9e7c882634ea550\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 4dcf63c423bf0e39aca2293d57f6792d023db649d6719fe936446904b9f7e60d\nA = 5bcdb514bbe84261e169203e8017909b60c9bb330400c766ee01b0189378e70e61867a164a12643ddc9e94b61e09e5b158cbe85be228a3cc48f95a552958b8f2\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = cf77c5c2d12a500b75cbfb1f3e66ee75d886b9365cf4f8b4d1bd18a6be0f387\nA = 4652ddc2ea7b460d8ec3c9059b8f9b5dae6cac55b51f2ad86fcb336b25235737965cc515e2ff0b54835015b7ebeeda6fadd986471d8cb424d309fc353d1e269\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 1e0549e4c5a26023e9d24fd8c67419960746f82b1ecd113bdac66f570a475d87\nA = 5f4a6d450ab1390d96ab1deaa0ba18f897cb63daf0c9e1ef6c08e804c26b5e842f6c08f13db5d4a6e88f07af2a3cb04fa06fc3e59c410b9356f025ed81acc74\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 144481a781d831c1ca046ca9e322d79ad4d2c6dd9f780bea9d1ced9cd20b7b23\nA = 4c254fabca441017132b9eacd4ca40a336db3e5c09715773fa07af095989a91cc968ff07a9ff56ed06b0ce0c5269f7b2ab68564ecab9f4467a7e96b6cc6b21b7\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 216fecc7667f488a3d2d102a38b46b4860ab858300b8638af4f34e1103fd73ba\nA = 17878f8048227573a9d70f53c0e76ff13fe9f56e9c984c92514d3d13dec23c816661f0618d21371b80dfd885cb59551bdf80046f65f22ea9b89c78645a6e455a\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 458e5e789ccd2417174f7e30bb31914b9656bd8cf2b9f5a9752a8737a67707bc\nA = 5c7d39a4bb04e69201aa519f80ee7e62ea14ca55e13656d1da3f45367e2fb2d061aa2940708d02ac67d35cd2ccf54a1bf95bcbc759779e692cfdcbb3aa1a05b\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 543125a16c2bb8b8f8a2c39c497e5224ec77533602d7dbe24002e32dcbd2ef1a\nA = 3413afae", + "333b2ad9ff45c7f3c7e5934b3127e8b1a55225958ee6ccf42423e81559bf070ad3f3353b78c0ffd41475af49f59d268ef78bdae879f5155e8d1cc07\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 10e16859c67bdb2eaab52a7c847dbf37162eda258a9f6262ebacfe4cbbbc1080\nA = 21ce7905894faf220bdf4a82a2d855994ca2dc9feaecaa53c7f146e1f49934215695e9bb46ba370b7005a90c399674caa8969eb442e7914d90f749774d7fd194\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 32a00586adc6f6cc2b1a04e1be0ab569fde235e1436c38b6af92bc5ebd60bc1c\nA = 350da4fd8cf03c12f7dd6ac6d3ab801a3413964083e374662aaf878d6838b97d4feb9e52cd307a25b113e101661a865463ee2480c626aa4e2ec437d72e7bae4c\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 971f75bc7afa8b4b50f1d4b05e52deac7d4836a08d30546f29649bf1ca6a247\nA = 655ed4c5d8d0afb4f9360372ee1ef1303898d2423e585108a3303faedb55064d2ef25666ed4c4d71fe6063fea1f3142b435714b0e30b339dd791d347c884654\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 48fa882b7cb6a29de9e3769f72eb67f1efd4d2af56f0c7e410c610efcbce2065\nA = 14f3503f33b243800eac1defaab33e04c01e80163fb3efd03860970cc016832431ca4fc6d1b760f4f40166b0b8b3c40dbebc81460cc10890172243770338f090\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 236fd7e397ea7f8bc2a288eb7236ca41936fa702b7dccca56c8852e147511f7d\nA = 1bbd0980feac854782813bcde4da85e8a054549a1b515e065da4236528035e756882e29e762cf60453e375cca9dc6ff637f9558bf86646e3b928f68f82af7efe\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 693f0cbe8c81b0afde0cd2f83e53795dcae6b0cc4ba930ab5c752400d787f14\nA = 7b20f9664b23907e152ab8c9a907f72e8670c1c38ab4cd1411ea7c2159c09aa131afe068929b8e6ad1409b74c04975180d1cd0a9fa74e923c3fd451e8da2c34\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 4a086c50b0bad576501ddb6280743b2c9d247841eb7f14d90561432ff7dca6f0\nA = 4367431ec0cd0d7626538b93a090c30fe0c97c18ca03b97ddae304b619112b5b4d02bf0f041fa3fd673f9ef2ceb07eb2079d11c56dd903b1a87e8252a97b8079\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 18f8433fa468d8065157708f1f1e53b8e31d39c6011fbc2bad93de1b5548e19c\nA = 739c032bb4139c199c40f548d37234298772e4ccb9d3ba28412b60ad23b4c465b0787e2382f1c5a4a87af2d20eb978b7dcbe73f2112249477d15c8a85e54a79\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 49e3c8eef5e067cabd51a7c01384ce05ab8f4342f655559d8a689eb7b20e0106\nA = 18400c2cc3e06b99b4e39c77b9af5ff0e9c683f1708321afa4cd5b6988d13b36b1d9eb4379b7902d9ceb40c03f814b2b6a01b90509bbb4532f13ab1571c4d04a\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 35548c530745f440329325cc8a5fbd90c16a7f0788879a4869bc4d4f73acda0e\nA = 181a3c5ab02566e7166c4d6d2f2bd4a8ecc25991a98d270bde80cf4332766a7068b14240bf5f5dcd45e90ef252596da3eb05b11d68b2063f7b3a825742593ca9\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 1ab7046e6af061ade5f9719008fa4d989007e2a579a134a5b9f19ec410984096\nA = 1008a03e211fab0d45856377079bc96b0776c2d4c0175661f3493246cea2ab0a02a706c85314fb707ad9906bedb2cfd577d62092ae08ff21d7b949373ea954c7\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 2be9e3e7515960d90f115b89f60dedc173a73ce163b4036e85b7b6a76fd90852\nA = 392053a9f0100540a8e1a0c353e922068a84dad3a4a8e8962fbc0bee2b6a06e20d08ade16eb1409a16acfcac3db5c43c421505e07035ca308b15c4a6db0864c0\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 5b301bb93bdcf050183107e36258b53b4805918114ea1c2227b0911d5b4dc077\nA = 55e55e5f94dc3d7aabc921f6469d85fa2e1e92a87347c57afad5872306ae69f9fb99297d1e3e793dd9e8632244208154de5da7114fd876383bf1422f7ece024\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 2df9609e2f5a5156c3260461b2ee52eacdef00bd8b091479813143a6c5283f71\nA = 2099325b7f12fe77353ddf3f2b2c5ef77b49671b150af954cf84e9675e3ecde3e057084641a633d19533b4712ab49924c8b5c31d591abcc88291f51253fa2a7\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = dfab751710e9008e25e422d1199d6fbec4dc7fba35b4da9d225a746eb4126a0\nA = c006af53d4737fb293584df6ffe2e4cb3fd8dc77fb7c1f13b97bb9c249e3ee5fb9feff7488265b3093906c08a4946f142ac7b491937d24bfba6413366ce371d\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 26bc030008d6c60a09fb0e16093a649fcb40c6c21a8e2da2353ba4b07c4f85d5\nA = 1eaabcfad2ed349ac9356e6f4da0b301266ddde811cb0f817aba8f5c10fb8b8ba9d0ef2dd386b668f16eac296118fdb8cb7afe1b865648c81c2fa3cf21f2711b\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 35051b1482ec2578f3dc0000a422cb5111e43c37f1ac20b1844d3de2128c4556\nA = 315ff9de178681116f2a5fa78eebf4818e1d680435eacdfaf9d0e5c4fc01fc034b352c82fd52c81ca30d68864952dacc99d08269c9dd7ca99ccf22da98c3840\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = a5474252885cacf004c460a7793ff0b0a2187bb1a9ed700ae3470199faef71f\nA = 19856fc1351c4b02abf573bb2fc6ff92355fa369d62bb8f2260fa772fb1693f509a56cad661930abcac049dd70f4b16bed4a4c172e73e772504c9990ce7f92f\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 12daf4722387ecf47de1b0b6b110a062dc5ea2685bc9dbde66b8d15622985029\nA = fb8479787069116abc42abfd7dc0c24d2ad04fe0c04b42a6dff714af715d17e0fd77855f950f264542b06d48e8818de813ddb7975798b7debefcdaa5ff86beb\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 397996ed5c0ac6ad32e43c337e9de421b87774cc162bf7ac7bbedf4a9029255e\nA = 5aa04353321bd2de92481be740357f979da464b53aa39111fdbb734cf7af6b3857d1baa08d3a126a3dd34a2fbae2bf2b84e900686c1d31505b390185acef5fe5\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 2cf4b844a54ba359dc592ef1b49f43fcfeae84d1087edfefdd0b9174b43c0a3c\nA = 365a8650510bcfd8fa87432f167cf487234c215857403b9270b5eebeafa48cd6da47fd60dc311b94d1d72baad0447c31f0b212d755f46c256e16e5e015e6546e\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 9277c73043ff767c3fa606f0cd66b9d854a600c8c18287f191ce277758c3f31\nA = 62cec3901626d03e8df66299a87c54b1f7a55cafc99f0b6bba1b5d51a3d2b7d2171c9135a9d8a5346d436e0136b12e515e703e3cd84ecfe154eb94c6772a6d72\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 4189e5a90c1b1abdc1c7c05b3587e6f362e06f927b6cf5f0d271aab3d6f90765\nA = 336b8d0f9dac842c696bc020f49c6aa023842c16f2052eb02f17959006554ca0012042c80c72590f21c6bf5a3714c9cb552aa69730e33db93a56a909b273f39\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 36ccd38cb5a6bd8a73bca55936a2227c503664422c2296faf7e2b1c6a375a43a\nA = fecfd60a376befbe48d2c4f6d070d716d2f403cd5daefbce62b720df44deb605162c8f20f49fd7ec30d4f8e70d803d45b3a44b5d912baa3410d991165d7c507\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 198fc8569be172dc9b71023ed3d42d2ba94bae4099643f6517ab03f540527fdb\nA = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ec\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 21b7f74c30ded681d6138cf8e6fd798f32a049e94138e982f1845df3dc9e686f\nA = 9a30b791c1ba4f394b4e3dcd5837e474237f4fe8987b255c098a47b2c14c598ec69d2beae444dd4fe9c4ede8173d2b187677cc706a3c28f3b81627d8a5fb6fd\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186\nA = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# NotModSquare tests.\n#\n# These test vectors are such that NotModSquare is not a square modulo P.\n\nNotModSquare = 03\nP = 07\n\nNotModSquare = 05\nP = 07\n\nNotModSquare = 06\nP = 07\n\nNotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# ModInv tests.\n#\n# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M.\n\nModInv = 00\nA = 00\nM = 01\n\nModInv = 00\nA = 01\nM = 01\n\nModInv = 00\nA = 02\nM = 01\n\nModInv = 00\nA ", + "= 03\nM = 01\n", }; -static const size_t kLen35 = 836140; +static const size_t kLen35 = 868364; static const char *kData36[] = { "# Negation tests.\n#\n# The following tests satisfy A = -B (mod P).\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000000\nB = 0000000000000000000000000000000000000000000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000001\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000003\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffffc\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000007\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffff8\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000000f\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffff0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000001f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffffe0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000003f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffffc0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000007f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffff80\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000000ff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffff00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000001ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffe00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000003ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffc00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000007ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffff800\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000fff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffff000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000001fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffe000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000003fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffc000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000007fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffff8000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000ffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffff0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000001ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffe0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000003ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffc0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000007ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffff80000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000fffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffff00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000001fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffe00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000003fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffc00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000007fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffff800000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000ffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffff000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000001ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffe000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000003ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffc000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000007ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffff8000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000fffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffff0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000001fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffe0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000003fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffc0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000007fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffff80000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000ffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000001ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffe00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000003ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffc00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000007ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffff800000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000fffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffff000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000001fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffe000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000003fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffc000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000007fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffff8000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000ffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffff0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000001ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffe0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000003ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffc0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000007ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffff80000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000fffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffff00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000001fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffe00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000003fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffc00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000007fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffff800000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000ffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffff000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000001ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffe000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000003ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffc000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000007ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffff8000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000fffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffff0000000000000\n\nTest = Negate\nA ",
diff --git a/third_party/boringssl/err_data.c b/third_party/boringssl/err_data.c index dbb34a3a..4dda17b 100644 --- a/third_party/boringssl/err_data.c +++ b/third_party/boringssl/err_data.c
@@ -185,43 +185,43 @@ 0x28340c5e, 0x283480ac, 0x283500ea, - 0x2c322cda, + 0x2c322cf7, 0x2c3292a5, - 0x2c332ce8, - 0x2c33acfa, - 0x2c342d0e, - 0x2c34ad20, - 0x2c352d3b, - 0x2c35ad4d, - 0x2c362d60, + 0x2c332d05, + 0x2c33ad17, + 0x2c342d2b, + 0x2c34ad3d, + 0x2c352d58, + 0x2c35ad6a, + 0x2c362d7d, 0x2c36832d, - 0x2c372d6d, - 0x2c37ad7f, - 0x2c382da4, - 0x2c38adbb, - 0x2c392dc9, - 0x2c39add9, - 0x2c3a2deb, - 0x2c3aadff, - 0x2c3b2e10, - 0x2c3bae2f, + 0x2c372d8a, + 0x2c37ad9c, + 0x2c382dc1, + 0x2c38add8, + 0x2c392de6, + 0x2c39adf6, + 0x2c3a2e08, + 0x2c3aae1c, + 0x2c3b2e2d, + 0x2c3bae4c, 0x2c3c12b7, 0x2c3c92cd, - 0x2c3d2e43, + 0x2c3d2e60, 0x2c3d92e6, - 0x2c3e2e60, - 0x2c3eae6e, - 0x2c3f2e86, - 0x2c3fae9e, - 0x2c402eab, + 0x2c3e2e7d, + 0x2c3eae8b, + 0x2c3f2ea3, + 0x2c3faebb, + 0x2c402ec8, 0x2c4091b8, - 0x2c412ebc, - 0x2c41aecf, + 0x2c412ed9, + 0x2c41aeec, 0x2c42117e, - 0x2c42aee0, + 0x2c42aefd, 0x2c430720, - 0x2c43ae21, - 0x2c442d92, + 0x2c43ae3e, + 0x2c442daf, 0x30320000, 0x30328015, 0x3033001f, @@ -448,65 +448,65 @@ 0x405fa21e, 0x4060222c, 0x4060a24e, - 0x40612292, - 0x4061a2ca, - 0x406222e1, - 0x4062a2f2, - 0x40632303, - 0x4063a318, - 0x4064232f, - 0x4064a35b, - 0x40652376, - 0x4065a38d, - 0x406623a5, - 0x4066a3cf, - 0x406723fa, - 0x4067a41b, - 0x40682463, - 0x4068a484, - 0x406924b6, - 0x4069a4e4, - 0x406a2505, - 0x406aa525, - 0x406b26ad, - 0x406ba6d0, - 0x406c26e6, - 0x406ca961, - 0x406d2990, - 0x406da9b8, - 0x406e29e6, - 0x406eaa33, - 0x406f2a52, - 0x406faa8a, - 0x40702a9d, - 0x4070aaba, + 0x406122af, + 0x4061a2e7, + 0x406222fe, + 0x4062a30f, + 0x40632320, + 0x4063a335, + 0x4064234c, + 0x4064a378, + 0x40652393, + 0x4065a3aa, + 0x406623c2, + 0x4066a3ec, + 0x40672417, + 0x4067a438, + 0x40682480, + 0x4068a4a1, + 0x406924d3, + 0x4069a501, + 0x406a2522, + 0x406aa542, + 0x406b26ca, + 0x406ba6ed, + 0x406c2703, + 0x406ca97e, + 0x406d29ad, + 0x406da9d5, + 0x406e2a03, + 0x406eaa50, + 0x406f2a6f, + 0x406faaa7, + 0x40702aba, + 0x4070aad7, 0x40710800, - 0x4071aacc, - 0x40722adf, - 0x4072aaf8, - 0x40732b10, + 0x4071aae9, + 0x40722afc, + 0x4072ab15, + 0x40732b2d, 0x407394a4, - 0x40742b24, - 0x4074ab3e, - 0x40752b4f, - 0x4075ab63, - 0x40762b71, + 0x40742b41, + 0x4074ab5b, + 0x40752b6c, + 0x4075ab80, + 0x40762b8e, 0x4076927b, - 0x40772b96, - 0x4077abb8, - 0x40782bd3, - 0x4078ac0c, - 0x40792c23, - 0x4079ac39, - 0x407a2c45, - 0x407aac58, - 0x407b2c6d, - 0x407bac7f, - 0x407c2cb0, - 0x407cacb9, - 0x407d249f, + 0x40772bb3, + 0x4077abd5, + 0x40782bf0, + 0x4078ac29, + 0x40792c40, + 0x4079ac56, + 0x407a2c62, + 0x407aac75, + 0x407b2c8a, + 0x407bac9c, + 0x407c2ccd, + 0x407cacd6, + 0x407d24bc, 0x407d9eca, - 0x407e2be8, + 0x407e2c05, 0x407ea0a3, 0x407f1c93, 0x407f9a53, @@ -514,66 +514,67 @@ 0x40809cbb, 0x40811f46, 0x40819e7b, - 0x408229d1, + 0x408229ee, 0x40829a39, 0x4083207e, - 0x4083a340, + 0x4083a35d, 0x40841ccf, 0x4084a0db, 0x40852160, 0x4085a276, 0x408621d2, 0x40869ee4, - 0x40872a17, - 0x4087a2a7, + 0x40872a34, + 0x4087a2c4, 0x40881a9a, - 0x4088a42e, + 0x4088a44b, 0x40891ae9, 0x40899a76, - 0x408a2706, + 0x408a2723, 0x408a9884, - 0x408b2c94, - 0x408baa67, + 0x408b2cb1, + 0x408baa84, 0x408c2170, 0x408c98a0, 0x408d1d12, 0x408d9ce3, 0x408e1e2c, 0x408e9fe6, - 0x408f2442, - 0x41f425d8, - 0x41f9266a, - 0x41fe255d, - 0x41fea752, - 0x41ff2843, - 0x420325f1, - 0x42082613, - 0x4208a64f, - 0x42092541, - 0x4209a689, - 0x420a2598, - 0x420aa578, - 0x420b25b8, - 0x420ba631, - 0x420c285f, - 0x420ca71f, - 0x420d2739, - 0x420da770, - 0x4212278a, - 0x42172826, - 0x4217a7cc, - 0x421c27ee, - 0x421f27a9, - 0x42212876, - 0x42262809, - 0x422b2945, - 0x422ba8f3, - 0x422c292d, - 0x422ca8b2, - 0x422d2891, - 0x422da912, - 0x422e28d8, - 0x422ea9fe, + 0x408f245f, + 0x408fa292, + 0x41f425f5, + 0x41f92687, + 0x41fe257a, + 0x41fea76f, + 0x41ff2860, + 0x4203260e, + 0x42082630, + 0x4208a66c, + 0x4209255e, + 0x4209a6a6, + 0x420a25b5, + 0x420aa595, + 0x420b25d5, + 0x420ba64e, + 0x420c287c, + 0x420ca73c, + 0x420d2756, + 0x420da78d, + 0x421227a7, + 0x42172843, + 0x4217a7e9, + 0x421c280b, + 0x421f27c6, + 0x42212893, + 0x42262826, + 0x422b2962, + 0x422ba910, + 0x422c294a, + 0x422ca8cf, + 0x422d28ae, + 0x422da92f, + 0x422e28f5, + 0x422eaa1b, 0x4432072b, 0x4432873a, 0x44330746, @@ -626,69 +627,69 @@ 0x4c4014c9, 0x4c4092f7, 0x4c4114ed, - 0x50322ef2, - 0x5032af01, - 0x50332f0c, - 0x5033af1c, - 0x50342f35, - 0x5034af4f, - 0x50352f5d, - 0x5035af73, - 0x50362f85, - 0x5036af9b, - 0x50372fb4, - 0x5037afc7, - 0x50382fdf, - 0x5038aff0, - 0x50393005, - 0x5039b019, - 0x503a3039, - 0x503ab04f, - 0x503b3067, - 0x503bb079, - 0x503c3095, - 0x503cb0ac, - 0x503d30c5, - 0x503db0db, - 0x503e30e8, - 0x503eb0fe, - 0x503f3110, + 0x50322f0f, + 0x5032af1e, + 0x50332f29, + 0x5033af39, + 0x50342f52, + 0x5034af6c, + 0x50352f7a, + 0x5035af90, + 0x50362fa2, + 0x5036afb8, + 0x50372fd1, + 0x5037afe4, + 0x50382ffc, + 0x5038b00d, + 0x50393022, + 0x5039b036, + 0x503a3056, + 0x503ab06c, + 0x503b3084, + 0x503bb096, + 0x503c30b2, + 0x503cb0c9, + 0x503d30e2, + 0x503db0f8, + 0x503e3105, + 0x503eb11b, + 0x503f312d, 0x503f8382, - 0x50403123, - 0x5040b133, - 0x5041314d, - 0x5041b15c, - 0x50423176, - 0x5042b193, - 0x504331a3, - 0x5043b1b3, - 0x504431c2, + 0x50403140, + 0x5040b150, + 0x5041316a, + 0x5041b179, + 0x50423193, + 0x5042b1b0, + 0x504331c0, + 0x5043b1d0, + 0x504431df, 0x5044843f, - 0x504531d6, - 0x5045b1f4, - 0x50463207, - 0x5046b21d, - 0x5047322f, - 0x5047b244, - 0x5048326a, - 0x5048b278, - 0x5049328b, - 0x5049b2a0, - 0x504a32b6, - 0x504ab2c6, - 0x504b32e6, - 0x504bb2f9, - 0x504c331c, - 0x504cb34a, - 0x504d335c, - 0x504db379, - 0x504e3394, - 0x504eb3b0, - 0x504f33c2, - 0x504fb3d9, - 0x505033e8, + 0x504531f3, + 0x5045b211, + 0x50463224, + 0x5046b23a, + 0x5047324c, + 0x5047b261, + 0x50483287, + 0x5048b295, + 0x504932a8, + 0x5049b2bd, + 0x504a32d3, + 0x504ab2e3, + 0x504b3303, + 0x504bb316, + 0x504c3339, + 0x504cb367, + 0x504d3379, + 0x504db396, + 0x504e33b1, + 0x504eb3cd, + 0x504f33df, + 0x504fb3f6, + 0x50503405, 0x505086ef, - 0x505133fb, + 0x50513418, 0x58320f3a, 0x68320efc, 0x68328c6a, @@ -1166,6 +1167,7 @@ "PEER_DID_NOT_RETURN_A_CERTIFICATE\0" "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\0" "PRE_SHARED_KEY_MUST_BE_LAST\0" + "PRIVATE_KEY_OPERATION_FAILED\0" "PROTOCOL_IS_SHUTDOWN\0" "PSK_IDENTITY_BINDER_COUNT_MISMATCH\0" "PSK_IDENTITY_NOT_FOUND\0"
diff --git a/third_party/metrics_proto/cast_logs.proto b/third_party/metrics_proto/cast_logs.proto index d203134..794f580 100644 --- a/third_party/metrics_proto/cast_logs.proto +++ b/third_party/metrics_proto/cast_logs.proto
@@ -191,7 +191,7 @@ optional fixed32 virtual_release_track = 4; // Cast specific device information which is expected to change over time. - // Next tag: 4 + // Next tag: 6 message CastDeviceMutableInfo { // This is the last type of reboot the device encountered // Next tag: 9 @@ -214,6 +214,19 @@ // An identifier that is specific to the combination of app and device, in // this case the one used by backdrop. optional string backdrop_app_device_id = 3; + + // IP version of the primary network interface. + enum NetifIPVersion { + IP_UNKNOWN = 0; + IP_V4 = 1; + IP_V6 = 2; + IP_DUAL_STACK = 3; + } + optional NetifIPVersion netif_ip_version = 4; + + // True if the system which cast_shell is running on, supports ip dual stack + // sockets. + optional bool ip_dual_stack_supported = 5; } optional CastDeviceMutableInfo cast_device_mutable_info = 5;
diff --git a/third_party/polymer/v1_0/bower.json b/third_party/polymer/v1_0/bower.json index 401007d..b74e5e10 100644 --- a/third_party/polymer/v1_0/bower.json +++ b/third_party/polymer/v1_0/bower.json
@@ -9,7 +9,7 @@ "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#1.0.13", "iron-behaviors": "PolymerElements/iron-behaviors#1.0.17", "iron-checked-element-behavior": "PolymerElements/iron-checked-element-behavior#1.0.5", - "iron-collapse": "PolymerElements/iron-collapse#1.2.1", + "iron-collapse": "PolymerElements/iron-collapse#2.1.0", "iron-dropdown": "PolymerElements/iron-dropdown#1.5.2", "iron-fit-behavior": "PolymerElements/iron-fit-behavior#1.2.5", "iron-flex-layout": "PolymerElements/iron-flex-layout#1.3.1", @@ -28,7 +28,7 @@ "iron-range-behavior": "PolymerElements/iron-range-behavior#1.0.6", "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#1.0.5", "iron-scroll-target-behavior": "PolymerElements/iron-scroll-target-behavior#1.1.0", - "iron-scroll-threshold": "PolymerElements/iron-scroll-threshold#1.0.2", + "iron-scroll-threshold": "PolymerElements/iron-scroll-threshold#2.0.0", "iron-selector": "PolymerElements/iron-selector#1.5.2", "iron-test-helpers": "PolymerElements/iron-test-helpers#2.0.0", "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#1.1.1",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-collapse/bower.json b/third_party/polymer/v1_0/components-chromium/iron-collapse/bower.json index e34d6eb..ca0d574 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-collapse/bower.json +++ b/third_party/polymer/v1_0/components-chromium/iron-collapse/bower.json
@@ -1,6 +1,6 @@ { "name": "iron-collapse", - "version": "1.2.1", + "version": "2.1.0", "description": "Provides a collapsable container", "authors": [ "The Polymer Authors" @@ -19,16 +19,36 @@ "homepage": "https://github.com/PolymerElements/iron-collapse", "ignore": [], "dependencies": { - "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0", - "polymer": "Polymer/polymer#^1.5.0" + "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#1 - 2", + "polymer": "Polymer/polymer#1.9 - 2" }, "devDependencies": { - "web-component-tester": "^4.0.0", - "test-fixture": "PolymerElements/test-fixture#^1.0.0", - "iron-component-page": "PolymerElements/iron-component-page#^1.0.0", - "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0", - "paper-styles": "PolymerElements/paper-styles#^1.0.0", - "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" + "iron-component-page": "PolymerElements/iron-component-page#1 - 2", + "paper-styles": "PolymerElements/paper-styles#1 - 2", + "iron-demo-helpers": "PolymerElements/iron-demo-helpers#1 - 2", + "web-component-tester": "^6.0.0", + "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0" }, - "main": "iron-collapse.html" + "variants": { + "1.x": { + "dependencies": { + "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0", + "polymer": "Polymer/polymer#^1.9" + }, + "devDependencies": { + "iron-component-page": "PolymerElements/iron-component-page#^1.0.0", + "paper-styles": "PolymerElements/paper-styles#^1.0.0", + "iron-demo-helpers": "PolymerElements/iron-demo-helpers#^1.0.0", + "web-component-tester": "^5.0.0", + "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" + }, + "resolutions": { + "webcomponentsjs": "^0.7" + } + } + }, + "main": "iron-collapse.html", + "resolutions": { + "webcomponentsjs": "^1.0.0" + } }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse-extracted.js index 8ff13505..83fa84af 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse-extracted.js +++ b/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse-extracted.js
@@ -32,6 +32,18 @@ }, /** + * When true, the element is transitioning its opened state. When false, + * the element has finished opening/closing. + * + * @attribute transitioning + */ + transitioning: { + type: Boolean, + notify: true, + readOnly: true + }, + + /** * Set noAnimation to true to disable animations. * * @attribute noAnimation @@ -73,16 +85,10 @@ hostAttributes: { role: 'group', 'aria-hidden': 'true', - 'aria-expanded': 'false' }, listeners: { - transitionend: '_transitionEnd' - }, - - attached: function() { - // It will take care of setting correct classes and styles. - this._transitionEnd(); + transitionend: '_onTransitionEnd' }, /** @@ -110,15 +116,13 @@ updateSize: function(size, animated) { // Consider 'auto' as '', to take full size. size = size === 'auto' ? '' : size; - // No change! - if (this._desiredSize === size) { - return; - } + + var willAnimate = animated && !this.noAnimation && + this.isAttached && this._desiredSize !== size; this._desiredSize = size; this._updateTransition(false); - var willAnimate = animated && !this.noAnimation && this._isDisplayed; // If we can animate, must do some prep work. if (willAnimate) { // Animation will start at the current size. @@ -171,9 +175,9 @@ }, _openedChanged: function() { - this.setAttribute('aria-expanded', this.opened); this.setAttribute('aria-hidden', !this.opened); + this._setTransitioning(true); this.toggleClass('iron-collapse-closed', false); this.toggleClass('iron-collapse-opened', false); this.updateSize(this.opened ? 'auto' : '0px', true); @@ -190,19 +194,13 @@ this.toggleClass('iron-collapse-opened', this.opened); this._updateTransition(false); this.notifyResize(); + this._setTransitioning(false); }, - /** - * Simplistic heuristic to detect if element has a parent with display: none - * - * @private - */ - get _isDisplayed() { - var rect = this.getBoundingClientRect(); - for (var prop in rect) { - if (rect[prop] !== 0) return true; + _onTransitionEnd: function(event) { + if (Polymer.dom(event).rootTarget === this) { + this._transitionEnd(); } - return false; }, _calcSize: function() {
diff --git a/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse.html b/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse.html index bd71fdba..a5b410f 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse.html +++ b/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse.html
@@ -64,6 +64,7 @@ :host { display: block; transition-duration: var(--iron-collapse-transition-duration, 300ms); + /* Safari 10 needs this property prefixed to correctly apply the custom property */ overflow: visible; } @@ -76,7 +77,7 @@ } </style> - <content></content> + <slot></slot> </template>
diff --git a/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/bower.json b/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/bower.json index 3fad871..7d06295 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/bower.json +++ b/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/bower.json
@@ -5,7 +5,7 @@ "web-components", "polymer" ], - "version": "1.0.2", + "version": "2.0.0", "homepage": "https://github.com/PolymerElements/iron-scroll-threshold", "authors": [ "The Polymer Authors" @@ -18,12 +18,30 @@ "license": "http://polymer.github.io/LICENSE.txt", "ignore": [], "dependencies": { - "polymer": "Polymer/polymer#^1.1.0", - "iron-scroll-target-behavior": "PolymerElements/iron-scroll-target-behavior#^1.0.0" + "polymer": "Polymer/polymer#1.9 - 2", + "iron-scroll-target-behavior": "PolymerElements/iron-scroll-target-behavior#1 - 2" }, "devDependencies": { - "iron-component-page": "polymerelements/iron-component-page#^1.0.0", - "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.2", - "web-component-tester": "^4.0.0" + "iron-component-page": "polymerelements/iron-component-page#1 - 2", + "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0", + "web-component-tester": "^6.0.0" + }, + "variants": { + "1.x": { + "dependencies": { + "polymer": "Polymer/polymer#^1.9", + "iron-scroll-target-behavior": "PolymerElements/iron-scroll-target-behavior#^1.0.0" + }, + "devDependencies": { + "iron-component-page": "polymerelements/iron-component-page#^1.0.0", + "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" + }, + "resolutions": { + "webcomponentsjs": "^0.7" + } + } + }, + "resolutions": { + "webcomponentsjs": "^1.0.0" } }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/iron-scroll-threshold-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/iron-scroll-threshold-extracted.js index d99fec4..95caf999 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/iron-scroll-threshold-extracted.js +++ b/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/iron-scroll-threshold-extracted.js
@@ -66,6 +66,7 @@ _setOverflow: function(scrollTarget) { this.style.overflow = scrollTarget === this ? 'auto' : ''; + this.style.webkitOverflowScrolling = scrollTarget === this ? 'touch' : ''; }, _scrollHandler: function() { @@ -73,7 +74,7 @@ var THROTTLE_THRESHOLD = 200; if (!this.isDebouncerActive('_checkTheshold')) { this.debounce('_checkTheshold', function() { - this.checkScrollThesholds(); + this.checkScrollThresholds(); }, THROTTLE_THRESHOLD); } }, @@ -82,7 +83,7 @@ if (isAttached) { this.debounce('_init', function() { this.clearTriggers(); - this.checkScrollThesholds(); + this.checkScrollThresholds(); }); } }, @@ -91,9 +92,9 @@ * Checks the scroll thresholds. * This method is automatically called by iron-scroll-threshold. * - * @method checkScrollThesholds + * @method checkScrollThresholds */ - checkScrollThesholds: function() { + checkScrollThresholds: function() { if (!this.scrollTarget || (this.lowerTriggered && this.upperTriggered)) { return; } @@ -114,6 +115,11 @@ } }, + checkScrollThesholds: function() { + // iron-scroll-threshold/issues/16 + this.checkScrollThresholds(); + }, + /** * Clear the upper and lower threshold states. *
diff --git a/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/iron-scroll-threshold.html b/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/iron-scroll-threshold.html index e5bde79..1e5537f 100644 --- a/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/iron-scroll-threshold.html +++ b/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/iron-scroll-threshold.html
@@ -82,7 +82,7 @@ } </style> - <content></content> + <slot></slot> </template> </dom-module>
diff --git a/third_party/polymer/v1_0/components_summary.txt b/third_party/polymer/v1_0/components_summary.txt index 3bab81e1..0b4b1f7 100644 --- a/third_party/polymer/v1_0/components_summary.txt +++ b/third_party/polymer/v1_0/components_summary.txt
@@ -42,9 +42,9 @@ Name: iron-collapse Repository: https://github.com/PolymerElements/iron-collapse.git -Tree: v1.2.1 -Revision: 5f994b1ac109925f6849b134e479229a16a752db -Tree link: https://github.com/PolymerElements/iron-collapse/tree/v1.2.1 +Tree: v2.1.0 +Revision: a805b8dd39cd30631f218298fd5315c4d93d1daa +Tree link: https://github.com/PolymerElements/iron-collapse/tree/v2.1.0 Name: iron-dropdown Repository: https://github.com/PolymerElements/iron-dropdown.git @@ -156,9 +156,9 @@ Name: iron-scroll-threshold Repository: https://github.com/PolymerElements/iron-scroll-threshold.git -Tree: v1.0.2 -Revision: 3b0ded11ea87703a4f1ef48cea93226fb0e71ef1 -Tree link: https://github.com/PolymerElements/iron-scroll-threshold/tree/v1.0.2 +Tree: v2.0.0 +Revision: e7bba05323f4779042c1e17e290860cf2b1a8ed5 +Tree link: https://github.com/PolymerElements/iron-scroll-threshold/tree/v2.0.0 Name: iron-selector Repository: https://github.com/PolymerElements/iron-selector.git
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium index a0fad7b..a50aa9c9 100644 --- a/third_party/protobuf/README.chromium +++ b/third_party/protobuf/README.chromium
@@ -109,4 +109,8 @@ - 0017-constexpr-for-vs-2017.patch Define PROTOBUF_CONSTEXPR_VAR as constexpr for VS 2017, also landed upstream - as https://github.com/google/protobuf/commit/210be267fd81d5aafdc049d197d57cb45b75f3ba \ No newline at end of file + as https://github.com/google/protobuf/commit/210be267fd81d5aafdc049d197d57cb45b75f3ba + +- 0018-fallthrough.patch + + Cherry-picks upstream https://github.com/google/protobuf/commit/b8e47830d
diff --git a/third_party/protobuf/patches/0018-fallthrough.patch b/third_party/protobuf/patches/0018-fallthrough.patch new file mode 100644 index 0000000..085e998 --- /dev/null +++ b/third_party/protobuf/patches/0018-fallthrough.patch
@@ -0,0 +1,38 @@ +diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h +index 1646ce4385..dc6ec9177e 100644 +--- a/src/google/protobuf/map_entry_lite.h ++++ b/src/google/protobuf/map_entry_lite.h +@@ -201,8 +201,7 @@ class MapEntryImpl : public Base { + return false; + } + set_has_key(); +- if (!input->ExpectTag(kValueTag)) break; +- GOOGLE_FALLTHROUGH_INTENDED; ++ break; + + case kValueTag: + if (!ValueTypeHandler::Read(input, mutable_value())) { +diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h +index 30bd7b1d71..27849298ea 100644 +--- a/src/google/protobuf/stubs/port.h ++++ b/src/google/protobuf/stubs/port.h +@@ -237,20 +237,6 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); + #define GOOGLE_SAFE_CONCURRENT_WRITES_END() + #endif + +-#if defined(__clang__) && defined(__has_cpp_attribute) \ +- && !defined(GOOGLE_PROTOBUF_OS_APPLE) +-# if defined(GOOGLE_PROTOBUF_OS_NACL) || defined(EMSCRIPTEN) || \ +- __has_cpp_attribute(clang::fallthrough) +-# define GOOGLE_FALLTHROUGH_INTENDED [[clang::fallthrough]] +-# endif +-#elif defined(__GNUC__) && __GNUC__ > 6 +-# define GOOGLE_FALLTHROUGH_INTENDED [[gnu::fallthrough]] +-#endif +- +-#ifndef GOOGLE_FALLTHROUGH_INTENDED +-# define GOOGLE_FALLTHROUGH_INTENDED +-#endif +- + #define GOOGLE_GUARDED_BY(x) + #define GOOGLE_ATTRIBUTE_COLD
diff --git a/third_party/protobuf/src/google/protobuf/map_entry_lite.h b/third_party/protobuf/src/google/protobuf/map_entry_lite.h index 1510449..b0307a6 100644 --- a/third_party/protobuf/src/google/protobuf/map_entry_lite.h +++ b/third_party/protobuf/src/google/protobuf/map_entry_lite.h
@@ -201,8 +201,7 @@ return false; } set_has_key(); - if (!input->ExpectTag(kValueTag)) break; - GOOGLE_FALLTHROUGH_INTENDED; + break; case kValueTag: if (!ValueTypeHandler::Read(input, mutable_value())) {
diff --git a/third_party/protobuf/src/google/protobuf/stubs/port.h b/third_party/protobuf/src/google/protobuf/stubs/port.h index d54ced0e..fb835b6 100644 --- a/third_party/protobuf/src/google/protobuf/stubs/port.h +++ b/third_party/protobuf/src/google/protobuf/stubs/port.h
@@ -253,18 +253,6 @@ #define GOOGLE_SAFE_CONCURRENT_WRITES_END() #endif -#if defined(__clang__) && defined(__has_cpp_attribute) \ - && !defined(GOOGLE_PROTOBUF_OS_APPLE) -# if defined(GOOGLE_PROTOBUF_OS_NACL) || defined(EMSCRIPTEN) || \ - __has_cpp_attribute(clang::fallthrough) -# define GOOGLE_FALLTHROUGH_INTENDED [[clang::fallthrough]] -# endif -#endif - -#ifndef GOOGLE_FALLTHROUGH_INTENDED -# define GOOGLE_FALLTHROUGH_INTENDED -#endif - #define GOOGLE_GUARDED_BY(x) #define GOOGLE_ATTRIBUTE_COLD
diff --git a/third_party/sqlite/BUILD.gn b/third_party/sqlite/BUILD.gn index a8f0d6c..79dceed 100644 --- a/third_party/sqlite/BUILD.gn +++ b/third_party/sqlite/BUILD.gn
@@ -77,6 +77,9 @@ "SQLITE_OMIT_SHARED_CACHE", "SQLITE_USE_ALLOCA", + # Chromium initializes SQLite manually in //sql/connection.cc. + "SQLITE_OMIT_AUTOINIT", + # Chromium calls sqlite3_reset() correctly to reset prepared statements. "SQLITE_OMIT_AUTORESET", @@ -98,9 +101,6 @@ # TODO(pwnall): Add SQLITE_OMIT_COMPLETE when we import a SQLite release # including https://www.sqlite.org/src/info/c3e816cca4ddf096 - - # TODO(pwnall): Add SQLITE_OMIT_AUTOINIT after the resolution and landing - # of https://crrev.com/c/894692 ] # On OSX, SQLite has extra logic for detecting the use of network
diff --git a/tools/android/sdk_updater/update_sdk.py b/tools/android/sdk_updater/update_sdk.py index 3ec2be98..7fad775 100755 --- a/tools/android/sdk_updater/update_sdk.py +++ b/tools/android/sdk_updater/update_sdk.py
@@ -24,10 +24,10 @@ (optional) $ update_sdk.py package --dry-run $ update_sdk.py package 2) updating a specified package: - $ update_sdk.py download -p build-tools;27.0.1 + $ update_sdk.py download -p "build-tools;27.0.3" (optional) $ update_sdk.py package --dry-run -p build-tools \ - --version 27.0.1 - $ update_sdk.py package -p build-tools --version 27.0.1 + --version 27.0.3 + $ update_sdk.py package -p build-tools --version 27.0.3 Note that `package` could update the package argument to the checkout version in .gn file //build/config/android/config.gni. If having git @@ -66,7 +66,7 @@ ] _DEFAULT_PACKAGES_DICT = { - 'build-tools': 'build-tools;27.0.1', + 'build-tools': 'build-tools;27.0.3', 'platforms': 'platforms;android-27', 'sources': 'sources;android-26', } @@ -131,7 +131,7 @@ # Installed packages:=====================] 100% Computing updates... # Path | Version | Description # ------- | ------- | ------- - # build-tools;27.0.1 | 27.0.1 | Android SDK Build-Tools 27.0.1 + # build-tools;27.0.3 | 27.0.3 | Android SDK Build-Tools 27.0.3 # emulator | 26.0.3 | Android Emulator # platforms;android-27 | 1 | Android SDK Platform 27 # tools | 26.1.1 | Android SDK Tools @@ -232,7 +232,7 @@ gn_arg_pattern = re.compile( # Match the argument with '=' and whitespaces. Capture a group for it. r'(^\s*%s\s*=\s*)' % version_config_name + - # version number with double quote. E.g. "27", "27.0.1", "-26.0.0-dev" + # version number with double quote. E.g. "27", "27.0.3", "-26.0.0-dev" r'([-\w\s."]+)' # End of string r'$' @@ -308,7 +308,7 @@ help='The packages of the SDK needs to be installed/updated. ' + 'Note that package name should be a sdk-style path e.g. ' + '"platforms;android-27" or "platform-tools". If package ' + - 'is not specified, update "build-tools;27.0.1", "tools" ' + + 'is not specified, update "build-tools;27.0.3", "tools" ' + '"platform-tools" and "platforms;android-27" by default.') download_parser.add_argument('--sdk-root', default=_SDK_ROOT,
diff --git a/tools/chrome_proxy/webdriver/video.py b/tools/chrome_proxy/webdriver/video.py index cb3b4840..4fe83f2 100644 --- a/tools/chrome_proxy/webdriver/video.py +++ b/tools/chrome_proxy/webdriver/video.py
@@ -124,7 +124,7 @@ def testVideoMetrics(self): expected = { 'duration': 3.068, - 'webkitDecodedFrameCount': 54.0, + 'webkitDecodedFrameCount': 53.0, 'videoWidth': 1280.0, 'videoHeight': 720.0 }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index e769e9e..2f7ca9e 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -6395,6 +6395,12 @@ <int value="14" label="QUIC/36"/> <int value="15" label="QUIC/37"/> <int value="16" label="QUIC/38"/> + <int value="17" label="QUIC/39"/> + <int value="18" label="QUIC/40"/> + <int value="19" label="QUIC/41"/> + <int value="20" label="QUIC/42"/> + <int value="21" label="QUIC/43"/> + <int value="22" label="QUIC/99"/> </enum> <enum name="ConnectionResult"> @@ -17612,7 +17618,7 @@ <int value="2199" label="BatteryStatusInsecureOrigin"/> <int value="2200" label="BatteryStatusCrossOrigin"/> <int value="2201" label="BatteryStatusSameOriginABA"/> - <int value="2202" label="WebAudioValueSetterIsSetValue"/> + <int value="2202" label="WebAudioValueSetterIsSetValue (Obsolete)"/> <int value="2203" label="HasIDClassTagAttribute"/> <int value="2204" label="HasBeforeOrAfterPseudoElement"/> <int value="2205" label="ShapeOutsideMaybeAffectedInlineSize"/> @@ -17777,6 +17783,7 @@ label="CertificateTransparencyNonCompliantResourceInSubframe"/> <int value="2361" label="V8AbortController_Constructor"/> <int value="2362" label="ReplaceCharsetInXHRIgnoringCase"/> + <int value="2363" label="HTMLIFrameElementGestureMedia"/> </enum> <enum name="FeedbackSource">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 461d691..c6a1e54 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -56294,6 +56294,9 @@ </histogram> <histogram name="OfflinePages.SavedPageCount" units="pages"> + <obsolete> + Deprecated as of 2/2018. Replaced by OfflinePages.SavedPageCountUponQuery. + </obsolete> <owner>jianli@chromium.org</owner> <summary> Number of saved pages restored from the offline pages metadata store when it @@ -56301,6 +56304,15 @@ </summary> </histogram> +<histogram name="OfflinePages.SavedPageCountUponQuery" units="pages"> + <owner>carlosk@chromium.org</owner> + <summary> + Total number of saved offline pages recorded when they are all queried from + the store. This value is more meaningful when filtered by unique users as + that eliminates multiple reports from the same Chrome instance. + </summary> +</histogram> + <histogram name="OfflinePages.SavePage.FreeSpaceMB" units="MB"> <owner>jianli@chromium.org</owner> <summary> @@ -82776,6 +82788,12 @@ <histogram base="true" name="SimpleCache.EntryCreatedAndStream2Omitted" enum="SimpleCache.EntryCreatedAndStream2Omitted"> + <obsolete> + Removed 2018-02. Not creating stream 2 on CreateEntry entries is indeed a + good idea, since stream 2 writes are done on things opened with OpenEntry. + (Which also means this metric wasn't good at evaluating the prevalence of + stream 2 in general). + </obsolete> <owner>morlovich@chromium.org</owner> <summary> Whether, upon creation of a new cache entry, the file for stream 2 was @@ -97241,6 +97259,9 @@ </histogram> <histogram name="WebAudio.AudioParam.ValueSetterConflictCount"> + <obsolete> + Removed 02/2018 in Issue 764396. Information no longer needed or recorded. + </obsolete> <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> @@ -97251,6 +97272,9 @@ </histogram> <histogram name="WebAudio.AudioParam.ValueSetterConflictPercentage"> + <obsolete> + Removed 02/2018 in Issue 764396. Information no longer needed or recorded. + </obsolete> <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> @@ -97261,6 +97285,9 @@ </histogram> <histogram name="WebAudio.AudioParam.ValueSetterCount"> + <obsolete> + Removed 02/2018 in Issue 764396. Information no longer needed or recorded. + </obsolete> <owner>rtoy@chromium.org</owner> <owner>hongchan@chromium.org</owner> <summary> @@ -106257,9 +106284,9 @@ <suffix name="MuteButton" label="Mute button"/> <suffix name="MuteOverflowButton" label="Mute overflow button"/> <suffix name="OverflowButton" label="Overflow button"/> - <suffix name="PictureInPictureButton" label="Picture in picture button"/> + <suffix name="PictureInPictureButton" label="Picture-in-Picture button"/> <suffix name="PictureInPictureOverflowButton" - label="Picture in picture overflow button"/> + label="Picture-in-Picture overflow button"/> <suffix name="PlayOverlayButton" label="Play overlay button"/> <suffix name="PlayPauseButton" label="Play/pause button"/> <suffix name="PlayPauseOverflowButton" label="Play/pause overflow button"/>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 0bbdc83..a4c46a4 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -105,5 +105,6 @@ v8.detached_context_age_in_gc,ulan@chromium.org, v8.runtime_stats.top_25,cbruni@chromium.org, validating_command_buffer_perftests,"piman@chromium.org, chrome-gpu-perf-owners@chromium.org",Internals>GPU +views_perftests,tapted@chromium.org,Internals>Views wasm,bradnelson@chromium.org, webrtc,"qiangchen@chromium.org, ehmaldonado@chromium.org, phoglund@chromium.org",
diff --git a/tools/perf/chromium.perf.fyi.extras.json b/tools/perf/chromium.perf.fyi.extras.json deleted file mode 100644 index c9fca6cd..0000000 --- a/tools/perf/chromium.perf.fyi.extras.json +++ /dev/null
@@ -1,511 +0,0 @@ -{ - "comment": [ - "This file contains manually-specified tests that should be merged into", - "testing/buildbot/chromium.perf.fyi.json." - ], - "Mojo Linux Perf": { - "isolated_scripts": [ - { - "args": [ - "loading.desktop.network_service", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=release", - "--xvfb" - ], - "isolate_name": "telemetry_perf_tests", - "name": "loading.desktop.network_service", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - } - ] - }, - "Histogram Pipeline Linux Perf": { - "isolated_scripts": [ - { - "args": [ - "dummy_benchmark.histogram_benchmark_1", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=release", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "dummy_benchmark.histogram_benchmark_1", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "dummy_benchmark.histogram_benchmark_1", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=reference", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "dummy_benchmark.histogram_benchmark_1.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "loading.desktop", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=release", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "loading.desktop", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "loading.desktop", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=reference", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "loading.desktop.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "system_health.common_desktop", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=release", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "system_health.common_desktop", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "system_health.common_desktop", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=reference", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "system_health.common_desktop.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "system_health.memory_desktop", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=release", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "system_health.memory_desktop", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "system_health.memory_desktop", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=reference", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "system_health.memory_desktop.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "speedometer2", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=release", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "speedometer2", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - }, - { - "args": [ - "speedometer2", - "-v", - "--upload-results", - "--output-format=histograms", - "--output-format=json-test-results", - "--browser=reference", - "--xvfb", - "--also-run-disabled-tests" - ], - "isolate_name": "telemetry_perf_tests", - "name": "speedometer2.reference", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - } - ] - }, - "One Buildbot Step Test Builder": { - "isolated_scripts": [ - { - "args": [ - "-v", - "--output-format=histograms", - "--output-format=json-test-results", - "--xvfb", - "--browser=reference" - ], - "isolate_name": "performance_test_suite", - "name": "performance_test_suite", - "override_compile_targets": [ - "performance_test_suite" - ], - "merge": { - "args": [ - "--configuration-name", - "buildbot-test" - ], - "script": "//tools/perf/process_perf_results.py" - }, - "trigger_script": { - "args": [ - "--multiple-trigger-configs", - "[{\"id\": \"swarm846-c4\", \"pool\": \"Chrome-perf-fyi\"}, {\"id\": \"swarm847-c4\", \"pool\": \"Chrome-perf-fyi\"}]" - ], - "script": "//testing/trigger_scripts/perf_device_trigger.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "pool": "Chrome-perf-fyi" - } - ], - "shards": 2, - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - } - ] - }, - "Android Nexus 5X Perf FYI": { - "isolated_scripts": [ - { - "args": [ - "experimental.startup.android.coldish", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "experimental.startup.android.coldish", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "id": "build46-b1--device1", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 3600, - "hard_timeout": 1080, - "ignore_task_failure": false, - "io_timeout": 360 - } - }, - { - "args": [ - "heap_profiling.mobile.disabled", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "heap_profiling.mobile.disabled", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "id": "build46-b1--device2", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 3600, - "hard_timeout": 1080, - "ignore_task_failure": false, - "io_timeout": 360 - } - }, - { - "args": [ - "heap_profiling.mobile.native", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "heap_profiling.mobile.native", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "id": "build46-b1--device2", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 3600, - "hard_timeout": 1080, - "ignore_task_failure": false, - "io_timeout": 360 - } - }, - { - "args": [ - "heap_profiling.mobile.pseudo", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "heap_profiling.mobile.pseudo", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "id": "build46-b1--device2", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 3600, - "hard_timeout": 1080, - "ignore_task_failure": false, - "io_timeout": 360 - } - }, - { - "args": [ - "smoothness.oop_rasterization.top_25_smooth", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "smoothness.oop_rasterization.top_25_smooth", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "id": "build46-b1--device2", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 3600, - "hard_timeout": 1080, - "ignore_task_failure": false, - "io_timeout": 360 - } - }, - { - "args": [ - "thread_times.oop_rasterization.key_mobile", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=android-chromium" - ], - "isolate_name": "telemetry_perf_tests", - "name": "thread_times.oop_rasterization.key_mobile", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "id": "build46-b1--device2", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 3600, - "hard_timeout": 1080, - "ignore_task_failure": false, - "io_timeout": 360 - } - } - - ] - }, - "Linux ChromeOS Perf (mus-viz)": { - "isolated_scripts": [ - { - "args": [ - "smoothness.top_25_smooth", - "-v", - "--upload-results", - "--output-format=chartjson", - "--browser=exact", - "--browser-executable=./chrome" - ], - "isolate_name": "telemetry_perf_tests", - "name": "smoothness.top_25_smooth", - "override_compile_targets": [ - "telemetry_perf_tests" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "id": "build34-a1", - "pool": "Chrome-perf-fyi" - } - ], - "expiration": 36000, - "hard_timeout": 10800, - "ignore_task_failure": false, - "io_timeout": 3600 - } - } - ] - } -}
diff --git a/tools/perf/contrib/cros_benchmarks/ui_smoothness_bench.py b/tools/perf/contrib/cros_benchmarks/ui_smoothness_bench.py new file mode 100644 index 0000000..17ced155 --- /dev/null +++ b/tools/perf/contrib/cros_benchmarks/ui_smoothness_bench.py
@@ -0,0 +1,20 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +from core import perf_benchmark + +from measurements import smoothness +import page_sets +from telemetry import benchmark +from telemetry import story as story_module + +@benchmark.Owner(emails=['chiniforooshan@chromium.org', 'sadrul@chromium.org']) +class CrosUiSmoothnessBenchmark(perf_benchmark.PerfBenchmark): + """Measures ChromeOS UI smoothness.""" + test = smoothness.Smoothness + page_set = page_sets.CrosUiCasesPageSet + SUPPORTED_PLATFORMS = [story_module.expectations.ALL_CHROMEOS] + + @classmethod + def Name(cls): + return 'cros_ui_smoothness'
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 599d1a9d..e055d9a 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -5,9 +5,11 @@ # pylint: disable=too-many-lines -"""Script to generate chromium.perf.json and chromium.perf.fyi.json in +"""Script to generate chromium.perf.json in the src/testing/buildbot directory and benchmark.csv in the src/tools/perf directory. Maintaining these files by hand is too unwieldy. +Note: chromium.perf.fyi.json is updated manuall for now until crbug.com/757933 +is complete. """ import collections import csv @@ -81,11 +83,6 @@ return waterfall -def get_fyi_waterfall_config(): - waterfall = {'builders':{}, 'testers': {}} - return waterfall - - # Additional compile targets to add to builders. # On desktop builders, chromedriver is added as an additional compile target. # The perf waterfall builds this target for each commit, and the resulting @@ -314,7 +311,8 @@ 'build134-m1', 'build135-m1', 'build136-m1' ], 'perf_tests': [ - ('media_perftests', 'build134-m1')] + ('media_perftests', 'build134-m1'), + ('views_perftests', 'build135-m1')] } ]) waterfall = add_tester( @@ -450,6 +448,7 @@ 'build161-m1', 'build162-m1'], 'perf_tests': [ ('net_perftests', 'build159-m1'), + ('views_perftests', 'build160-m1'), ] } ]) @@ -505,7 +504,9 @@ ('load_library_perf_tests', 'build29-a9'), ('net_perftests', 'build29-a9'), ('tracing_perftests', 'build29-a9'), - ('media_perftests', 'build30-a9')] + ('media_perftests', 'build30-a9'), + ('views_perftests', 'build31-a9') + ] } ]) @@ -871,36 +872,11 @@ return os.path.join(buildbot_dir, filename) -def get_extras_json_config_file_for_waterfall(waterfall): - filename = '%s.extras.json' % waterfall['name'] - buildbot_dir = os.path.join(path_util.GetChromiumSrcDir(), 'tools', 'perf') - return os.path.join(buildbot_dir, filename) - - -def append_extra_tests(waterfall, tests): - """Appends extra tests to |tests|. - - Those extra tests are loaded from tools/perf/<waterfall name>.extras.json. - """ - extra_config_file = get_extras_json_config_file_for_waterfall(waterfall) - if os.path.isfile(extra_config_file): - with open(extra_config_file) as extra_fp: - extra_tests = json.load(extra_fp) - for key, value in extra_tests.iteritems(): - if key == 'comment': - continue - assert key not in tests - tests[key] = value - - def update_all_tests(waterfalls): all_tests = {} for w in waterfalls: tests = generate_all_tests(w) - # Note: |all_tests| don't cover those manually-specified tests added by - # append_extra_tests(). all_tests.update(tests) - append_extra_tests(w, tests) config_file = get_json_config_file_for_waterfall(w) with open(config_file, 'w') as fp: json.dump(tests, fp, indent=2, separators=(',', ': '), sort_keys=True) @@ -934,7 +910,9 @@ 'load_library_perf_tests': BenchmarkMetadata(None, None, False), 'media_perftests': BenchmarkMetadata('crouleau@chromium.org', None, False), 'performance_browser_tests': BenchmarkMetadata( - 'miu@chromium.org', None, False) + 'miu@chromium.org', None, False), + 'views_perftests': BenchmarkMetadata( + 'tapted@chromium.org', 'Internals>Views', False) } @@ -1065,8 +1043,6 @@ def main(): waterfall = get_waterfall_config() waterfall['name'] = 'chromium.perf' - fyi_waterfall = get_fyi_waterfall_config() - fyi_waterfall['name'] = 'chromium.perf.fyi' - update_all_tests([fyi_waterfall, waterfall]) + update_all_tests([waterfall]) update_benchmark_csv()
diff --git a/tools/perf/core/perf_data_generator_unittest.py b/tools/perf/core/perf_data_generator_unittest.py index 3d9b24a..18b1b2e 100644 --- a/tools/perf/core/perf_data_generator_unittest.py +++ b/tools/perf/core/perf_data_generator_unittest.py
@@ -234,33 +234,6 @@ 'build2-b1': ['other_test', 'test'], })) - def testExtraTestsAreLoadedFromFile(self): - tests = { - 'Linux Perf': {} - } - - mock_extras_json = ''' - { - "comment": [ "This is comment and therefore should be skipped." ], - "Mojo Linux Perf": {} - } - ''' - - mock_waterfall_name = 'hello' - - def mockIsFile(path): - return path.endswith('%s.extras.json' % mock_waterfall_name) - - with mock.patch('os.path.isfile', side_effect=mockIsFile): - with mock.patch('__builtin__.open', - mock.mock_open(read_data=mock_extras_json)): - perf_data_generator.append_extra_tests({'name': mock_waterfall_name}, - tests) - - self.assertTrue('Linux Perf' in tests) - self.assertTrue('Mojo Linux Perf' in tests) - self.assertFalse('comment' in tests) - def testShouldBenchmarksBeScheduledBadOS(self): class RegularBenchmark(benchmark.Benchmark): @classmethod
diff --git a/tools/perf/page_sets/cros_ui_cases.py b/tools/perf/page_sets/cros_ui_cases.py new file mode 100644 index 0000000..a2fc948 --- /dev/null +++ b/tools/perf/page_sets/cros_ui_cases.py
@@ -0,0 +1,61 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +from telemetry.page import page as page_module +from telemetry.page import shared_page_state +from telemetry import story + +class _SharedPageState(shared_page_state.SharedDesktopPageState): + + def CanRunOnBrowser(self, browser_info, page): + if not hasattr(page, 'CanRunOnBrowser'): + return True + return page.CanRunOnBrowser(browser_info.browser) + + +class DesktopUIPage(page_module.Page): + + def __init__(self, url, page_set, name): + super(DesktopUIPage, self).__init__( + url=url, + page_set=page_set, + name=name, + shared_page_state_class=_SharedPageState, + extra_browser_args=['--always-request-presentation-time']) + + +class OverviewMode(DesktopUIPage): + + def CanRunOnBrowser(self, browser): + return browser.supports_overview_mode + + def RunPageInteractions(self, action_runner): + action_runner.Wait(1) + # TODO(chiniforooshan): CreateInteraction creates an async event in the + # renderer, which works fine; it is nicer if we create UI interaction + # records in the browser process. + with action_runner.CreateInteraction('ui_EnterOverviewAction'): + action_runner.EnterOverviewMode() + # TODO(chiniforooshan): The follwoing wait, and the one after + # ExitOverviewMode(), is a workaround for crbug.com/788454. Remove when + # the bug is fixed. + action_runner.Wait(1) + action_runner.Wait(0.5) + with action_runner.CreateInteraction('ui_ExitOverviewAction'): + action_runner.ExitOverviewMode() + action_runner.Wait(1) + + +class CrosUiCasesPageSet(story.StorySet): + """Pages that test desktop UI performance.""" + + def __init__(self): + super(CrosUiCasesPageSet, self).__init__( + archive_data_file='data/cros_ui_cases.json', + cloud_storage_bucket=story.PARTNER_BUCKET) + + self.AddStory(OverviewMode( + 'http://news.yahoo.com', self, 'overview:yahoo_news')) + self.AddStory(OverviewMode( + 'http://jsbin.com/giqafofe/1/quiet?JS_POSTER_CIRCLE', self, + 'overview:js_poster_circle'))
diff --git a/tools/perf/page_sets/data/cros_ui_cases.json b/tools/perf/page_sets/data/cros_ui_cases.json new file mode 100644 index 0000000..ed41de5 --- /dev/null +++ b/tools/perf/page_sets/data/cros_ui_cases.json
@@ -0,0 +1,12 @@ +{ + "archives": { + "overview:js_poster_circle": { + "DEFAULT": "cros_ui_cases_000.wprgo" + }, + "overview:yahoo_news": { + "DEFAULT": "cros_ui_cases_000.wprgo" + } + }, + "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.", + "platform_specific": true +}
diff --git a/tools/perf/page_sets/data/cros_ui_cases_000.wprgo.sha1 b/tools/perf/page_sets/data/cros_ui_cases_000.wprgo.sha1 new file mode 100644 index 0000000..55ea51e3 --- /dev/null +++ b/tools/perf/page_sets/data/cros_ui_cases_000.wprgo.sha1
@@ -0,0 +1 @@ +ea990882aea7b63d9c22c4c079a5756164bd69ff \ No newline at end of file
diff --git a/tools/perf/page_sets/data/wasm_realworld_pages.json b/tools/perf/page_sets/data/wasm_realworld_pages.json index eda2b28..cc8d5da4 100644 --- a/tools/perf/page_sets/data/wasm_realworld_pages.json +++ b/tools/perf/page_sets/data/wasm_realworld_pages.json
@@ -1,13 +1,19 @@ { "archives": { "WasmSpaceBuggy": { - "DEFAULT": "wasm_realworld_pages_002.wprgo" + "DEFAULT": "wasm_realworld_pages_003.wprgo" + }, + "WasmStylizedRenderer": { + "DEFAULT": "wasm_realworld_pages_003.wprgo" + }, + "WasmSunTemple": { + "DEFAULT": "wasm_realworld_pages_003.wprgo" }, "WasmTanks": { - "DEFAULT": "wasm_realworld_pages_002.wprgo" + "DEFAULT": "wasm_realworld_pages_003.wprgo" }, "WasmZenGarden": { - "DEFAULT": "wasm_realworld_pages_002.wprgo" + "DEFAULT": "wasm_realworld_pages_003.wprgo" } }, "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
diff --git a/tools/perf/page_sets/data/wasm_realworld_pages_003.wprgo.sha1 b/tools/perf/page_sets/data/wasm_realworld_pages_003.wprgo.sha1 new file mode 100644 index 0000000..e0f524a --- /dev/null +++ b/tools/perf/page_sets/data/wasm_realworld_pages_003.wprgo.sha1
@@ -0,0 +1 @@ +232959afb464037f766a9ed0ea9918d358dde75b \ No newline at end of file
diff --git a/tools/perf/page_sets/top_25_smooth.py b/tools/perf/page_sets/top_25_smooth.py index 38d6804..6ae9e27 100644 --- a/tools/perf/page_sets/top_25_smooth.py +++ b/tools/perf/page_sets/top_25_smooth.py
@@ -28,45 +28,6 @@ return DerivedSmoothPage -class _SharedPageState(shared_page_state.SharedDesktopPageState): - - def CanRunOnBrowser(self, browser_info, page): - if not hasattr(page, 'CanRunOnBrowser'): - return True - return page.CanRunOnBrowser(browser_info.browser) - - -class DesktopUIPage(page_module.Page): - - def __init__(self, url, page_set, name): - super(DesktopUIPage, self).__init__( - url=url, page_set=page_set, name=name, - shared_page_state_class=_SharedPageState, - extra_browser_args='--always-request-presentation-time') - - -class OverviewMode(DesktopUIPage): - - def CanRunOnBrowser(self, browser): - return browser.supports_overview_mode - - def RunPageInteractions(self, action_runner): - action_runner.Wait(1) - # TODO(chiniforooshan): CreateInteraction creates an async event in the - # renderer, which works fine; it is nicer if we create UI interaction - # records in the browser process. - with action_runner.CreateInteraction('ui_EnterOverviewAction'): - action_runner.EnterOverviewMode() - # TODO(chiniforooshan): The follwoing wait, and the one after - # ExitOverviewMode(), is a workaround for crbug.com/788454. Remove when - # the bug is fixed. - action_runner.Wait(1) - action_runner.Wait(0.5) - with action_runner.CreateInteraction('ui_ExitOverviewAction'): - action_runner.ExitOverviewMode() - action_runner.Wait(1) - - class TopSmoothPage(page_module.Page): def __init__(self, url, page_set, name='', extra_browser_args=None): @@ -76,7 +37,7 @@ url=url, page_set=page_set, name=name, - shared_page_state_class=_SharedPageState, + shared_page_state_class=shared_page_state.SharedDesktopPageState, extra_browser_args=extra_browser_args) def RunPageInteractions(self, action_runner): @@ -161,7 +122,7 @@ self.scroll_forever = scroll_forever - desktop_state_class = _SharedPageState + desktop_state_class = shared_page_state.SharedDesktopPageState smooth_page_classes = [ GmailSmoothPage, @@ -217,10 +178,3 @@ for url in other_urls: self.AddStory(TopSmoothPage(url, self)) - - # Add UI stories. - self.AddStory(OverviewMode( - 'http://news.yahoo.com', self, 'overview:yahoo_news')) - self.AddStory(OverviewMode( - 'http://jsbin.com/giqafofe/1/quiet?JS_POSTER_CIRCLE', self, - 'overview:js_poster_circle'))
diff --git a/tools/perf/page_sets/wasm_realworld_pages.py b/tools/perf/page_sets/wasm_realworld_pages.py index 353a8c0..b035834e 100644 --- a/tools/perf/page_sets/wasm_realworld_pages.py +++ b/tools/perf/page_sets/wasm_realworld_pages.py
@@ -63,16 +63,15 @@ .contentDocument.getElementsByClassName('panel level-select')[0] .style.bottom == '-100px'""") -class EpicZenGarden(page_module.Page): +class EpicPageSet(page_module.Page): - def __init__(self, page_set): - url = 'https://s3.amazonaws.com/mozilla-games/ZenGarden/EpicZenGarden.html' - super(EpicZenGarden, self).__init__( + def __init__(self, page_set, url, name): + super(EpicPageSet, self).__init__( url=url, page_set=page_set, shared_page_state_class=( webgl_supported_shared_state.WebGLSupportedSharedState), - name='WasmZenGarden') + name=name) @property def skipped_gpus(self): @@ -84,6 +83,29 @@ .getElementById('fullscreen_request').style.display === 'inline-block'""") +class EpicZenGarden(EpicPageSet): + + def __init__(self, page_set): + url = 'https://s3.amazonaws.com/mozilla-games/ZenGarden/EpicZenGarden.html' + super(EpicZenGarden, self).__init__( + page_set=page_set, url=url, name='WasmZenGarden') + +class EpicSunTemple(EpicPageSet): + + def __init__(self, page_set): + url = ("https://s3.amazonaws.com/mozilla-games/tmp/2017-02-21-SunTemple/" + "SunTemple.html") + super(EpicSunTemple, self).__init__( + page_set=page_set, url=url, name='WasmSunTemple') + +class EpicStylizedRenderer(EpicPageSet): + + def __init__(self, page_set): + url = ("https://s3.amazonaws.com/mozilla-games/tmp/2017-02-21-StylizedRen" + "dering/StylizedRendering.html") + super(EpicStylizedRenderer, self).__init__( + page_set=page_set, url=url, name='WasmStylizedRenderer') + class WasmRealWorldPagesStorySet(story.StorySet): """Top apps, used to monitor web assembly apps.""" @@ -95,3 +117,5 @@ self.AddStory(Tanks(self)) self.AddStory(SpaceBuggy(self)) self.AddStory(EpicZenGarden(self)) + self.AddStory(EpicSunTemple(self)) + self.AddStory(EpicStylizedRenderer(self))
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py index 5d1f34c..b73e7079 100755 --- a/tools/perf/process_perf_results.py +++ b/tools/perf/process_perf_results.py
@@ -15,26 +15,25 @@ RESULTS_URL = 'https://chromeperf.appspot.com' -def _upload_perf_results(jsons_to_upload, name, configuration_name, +def _upload_perf_results(json_to_upload, name, configuration_name, build_properties): """Upload the contents of result JSON(s) to the perf dashboard.""" build_properties = json.loads(build_properties) - for results_file in jsons_to_upload: - args = [ - '--build-dir', '/b/c/b/obbs_fyi/src/out', - '--buildername', build_properties['buildername'], - '--buildnumber', build_properties['buildnumber'], - '--name', name, - '--configuration-name', configuration_name, - '--results-file', results_file, - '--results-url', RESULTS_URL, - '--got-revision-cp', build_properties['got_revision_cp'], - '--got-v8-revision', build_properties['got_v8_revision'], - '--got-webrtc-revision', build_properties['got_webrtc_revision'], - '--chromium-checkout-dir', '/b/c/b/obbs_fyi', - '--send-as-histograms', - ] - upload_results_to_perf_dashboard.main(args) + args = [ + '--build-dir', '/b/c/b/obbs_fyi/src/out', + '--buildername', build_properties['buildername'], + '--buildnumber', build_properties['buildnumber'], + '--name', name, + '--configuration-name', configuration_name, + '--results-file', json_to_upload, + '--results-url', RESULTS_URL, + '--got-revision-cp', build_properties['got_revision_cp'], + '--got-v8-revision', build_properties['got_v8_revision'], + '--got-webrtc-revision', build_properties['got_webrtc_revision'], + '--chromium-checkout-dir', '/b/c/b/obbs_fyi', + '--send-as-histograms', + ] + upload_results_to_perf_dashboard.main(args) def _merge_json_output(output_json, jsons_to_merge): @@ -59,44 +58,34 @@ Consists of merging the json-test-format output and uploading the perf test output (chartjson and histogram). - """ - shard_json_output_list = [] - shard_perf_results_file_list = [] - dir_list = [ + Each directory in the task_output_dir represents one benchmark + that was run. Within this directory, there is a subdirectory with the name + of the benchmark that was run. In that subdirectory, there is a + perftest-output.json file containing the performance results in histogram + or dashboard json format and an output.json file containing the json test + results for the benchmark. + """ + directory_list = [ f for f in listdir(task_output_dir) if not isfile(join(task_output_dir, f)) ] - benchmark_dir_list = [] - for directory in dir_list: - b_dir_list = [ + benchmark_directory_list = [] + for directory in directory_list: + benchmark_directory_list += [ join(task_output_dir, directory, f) for f in listdir(join(task_output_dir, directory)) ] - benchmark_dir_list += b_dir_list - print 'benchmark_dir_list ' - print benchmark_dir_list - # Each directory in the bot's output_dir should represent one benchmark - # that was run. Within this directory, there should be a perftest-output.json - # file containing the performance results in histogram or dashboard json - # format and an output.json file containing the json test results for the - # benchmark. - for directory in benchmark_dir_list: - shard_perf_results_file_list.append( - join(directory, 'perf_results.json')) - shard_json_output_list.append( - join(directory, 'test_results.json')) - shard_json_results = [] - for shard in shard_json_output_list: - with open(shard) as json_data: - shard_json_results.append(json.load(json_data)) + test_results_list = [] + for directory in benchmark_directory_list: + with open(join(directory, 'test_results.json')) as json_data: + test_results_list.append(json.load(json_data)) + _merge_json_output(output_json, test_results_list) - _merge_json_output(output_json, shard_json_results) - - # The name here should be the benchmark name which we need to parse out still. - _upload_perf_results(shard_perf_results_file_list, 'still tbd step name', - configuration_name, build_properties) + for directory in benchmark_directory_list: + _upload_perf_results(join(directory, 'perf_results.json'), + directory, configuration_name, build_properties) return 0
diff --git a/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java b/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java index 621db90e..f2781330 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java +++ b/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java
@@ -11,8 +11,10 @@ import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; +import android.widget.AdapterView; import android.widget.ListAdapter; import android.widget.ListPopupWindow; +import android.widget.ListView; import android.widget.PopupWindow; import org.chromium.base.ApiCompatibilityUtils; @@ -22,8 +24,7 @@ /** * The dropdown list popup window. */ -public class DropdownPopupWindow extends ListPopupWindow { - +public class DropdownPopupWindow { private final Context mContext; private final View mAnchorView; private boolean mRtl; @@ -31,6 +32,7 @@ private OnLayoutChangeListener mLayoutChangeListener; private PopupWindow.OnDismissListener mOnDismissListener; private CharSequence mDescription; + private ListPopupWindow mListPopupWindow; ListAdapter mAdapter; /** @@ -39,7 +41,7 @@ * @param anchorView Popup view to be anchored. */ public DropdownPopupWindow(Context context, View anchorView) { - super(context, null, 0, R.style.DropdownPopupWindow); + mListPopupWindow = new ListPopupWindow(context, null, 0, R.style.DropdownPopupWindow); mContext = context; mAnchorView = anchorView; @@ -55,7 +57,7 @@ }; mAnchorView.addOnLayoutChangeListener(mLayoutChangeListener); - super.setOnDismissListener(new PopupWindow.OnDismissListener() { + mListPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { if (mOnDismissListener != null) { @@ -66,16 +68,21 @@ } }); - setAnchorView(mAnchorView); + mListPopupWindow.setAnchorView(mAnchorView); Rect originalPadding = new Rect(); - getBackground().getPadding(originalPadding); - setVerticalOffset(-originalPadding.top); + mListPopupWindow.getBackground().getPadding(originalPadding); + mListPopupWindow.setVerticalOffset(-originalPadding.top); } - @Override + /** + * Sets the adapter that provides the data and the views to represent the data + * in this popup window. + * + * @param adapter The adapter to use to create this window's content. + */ public void setAdapter(ListAdapter adapter) { mAdapter = adapter; - super.setAdapter(adapter); + mListPopupWindow.setAdapter(adapter); } @@ -86,43 +93,47 @@ /** * Shows the popup. The adapter should be set before calling this method. */ - @Override public void show() { // An ugly hack to keep the popup from expanding on top of the keyboard. - setInputMethodMode(INPUT_METHOD_NEEDED); + mListPopupWindow.setInputMethodMode(mListPopupWindow.INPUT_METHOD_NEEDED); assert mAdapter != null : "Set the adapter before showing the popup."; final int contentWidth = UiUtils.computeMaxWidthOfListAdapterItems(mAdapter); final float anchorWidth = mAnchorView.getLayoutParams().width; assert anchorWidth > 0; Rect padding = new Rect(); - getBackground().getPadding(padding); + mListPopupWindow.getBackground().getPadding(padding); if (contentWidth + padding.left + padding.right > anchorWidth) { - setContentWidth(contentWidth); + mListPopupWindow.setContentWidth(contentWidth); final Rect displayFrame = new Rect(); mAnchorView.getWindowVisibleDisplayFrame(displayFrame); - if (getWidth() > displayFrame.width()) { - setWidth(displayFrame.width()); + if (mListPopupWindow.getWidth() > displayFrame.width()) { + mListPopupWindow.setWidth(displayFrame.width()); } } else { - setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); + mListPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); } - boolean wasShowing = isShowing(); - super.show(); - getListView().setDividerHeight(0); - ApiCompatibilityUtils.setLayoutDirection(getListView(), + boolean wasShowing = mListPopupWindow.isShowing(); + mListPopupWindow.show(); + mListPopupWindow.getListView().setDividerHeight(0); + ApiCompatibilityUtils.setLayoutDirection(mListPopupWindow.getListView(), mRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); if (!wasShowing) { - getListView().setContentDescription(mDescription); - getListView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + mListPopupWindow.getListView().setContentDescription(mDescription); + mListPopupWindow.getListView().sendAccessibilityEvent( + AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } if (mInitialSelection >= 0) { - getListView().setSelection(mInitialSelection); + mListPopupWindow.getListView().setSelection(mInitialSelection); mInitialSelection = -1; } } - @Override + /** + * Set a listener to receive a callback when the popup is dismissed. + * + * @param listener Listener that will be notified when the popup is dismissed. + */ public void setOnDismissListener(PopupWindow.OnDismissListener listener) { mOnDismissListener = listener; } @@ -147,7 +158,7 @@ try { Method setForceIgnoreOutsideTouch = ListPopupWindow.class.getMethod( "setForceIgnoreOutsideTouch", new Class[] { boolean.class }); - setForceIgnoreOutsideTouch.invoke(this, new Object[] { true }); + setForceIgnoreOutsideTouch.invoke(mListPopupWindow, new Object[] {true}); } catch (Exception e) { Log.e("AutofillPopup", "ListPopupWindow.setForceIgnoreOutsideTouch not found", @@ -165,6 +176,44 @@ } /** + * Sets a listener to receive events when a list item is clicked. + * + * @param clickListener Listener to register + */ + public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) { + mListPopupWindow.setOnItemClickListener(clickListener); + } + + /** + * Show the popup. Will have no effect if the popup is already showing. + * Post a {@link #show()} call to the UI thread. + */ + public void postShow() { + mListPopupWindow.postShow(); + } + + /** + * Disposes of the popup window. + */ + public void dismiss() { + mListPopupWindow.dismiss(); + } + + /** + * @return The {@link ListView} displayed within the popup window. + */ + public ListView getListView() { + return mListPopupWindow.getListView(); + } + + /** + * @return Whether the popup is currently showing. + */ + public boolean isShowing() { + return mListPopupWindow.isShowing(); + } + + /** * Measures the width of the list content. The adapter should not be null. * @return The popup window width in pixels. */
diff --git a/ui/app_list/app_list_view_delegate.h b/ui/app_list/app_list_view_delegate.h index 485d70cb3..1a98cf9 100644 --- a/ui/app_list/app_list_view_delegate.h +++ b/ui/app_list/app_list_view_delegate.h
@@ -28,7 +28,6 @@ class AppListModel; class AppListViewDelegateObserver; class SearchModel; -class SearchResult; class APP_LIST_EXPORT AppListViewDelegate { public: @@ -49,17 +48,18 @@ virtual void StartSearch(const base::string16& raw_query) = 0; // Invoked to open the search result. - virtual void OpenSearchResult(SearchResult* result, + virtual void OpenSearchResult(const std::string& result_id, int event_flags) = 0; - // Called to invoke a custom action on |result|. |action_index| corresponds - // to the index of an icon in |result.action_icons()|. - virtual void InvokeSearchResultAction(SearchResult* result, + // Called to invoke a custom action on a result with |result_id|. + // |action_index| corresponds to the index of an icon in + // |result.action_icons()|. + virtual void InvokeSearchResultAction(const std::string& result_id, int action_index, int event_flags) = 0; // Invoked when the app list is shown. - virtual void ViewShown() = 0; + virtual void ViewShown(int64_t display_id) = 0; // Invoked to dismiss app list. This may leave the view open but hidden from // the user.
diff --git a/ui/app_list/presenter/app_list_presenter_impl.cc b/ui/app_list/presenter/app_list_presenter_impl.cc index 3f7ea0e..99405e93 100644 --- a/ui/app_list/presenter/app_list_presenter_impl.cc +++ b/ui/app_list/presenter/app_list_presenter_impl.cc
@@ -86,16 +86,16 @@ ScheduleAnimation(); } else { presenter_delegate_ = factory_->GetDelegate(this); - AppListViewDelegate* view_delegate = presenter_delegate_->GetViewDelegate(); - DCHECK(view_delegate); + view_delegate_ = presenter_delegate_->GetViewDelegate(); + DCHECK(view_delegate_); // Note the AppListViewDelegate outlives the AppListView. For Ash, the view // is destroyed when dismissed. - AppListView* view = new AppListView(view_delegate); + AppListView* view = new AppListView(view_delegate_); presenter_delegate_->Init(view, display_id, current_apps_page_); SetView(view); } presenter_delegate_->OnShown(display_id); - presenter_delegate_->GetViewDelegate()->ViewShown(); + view_delegate_->ViewShown(display_id); } void AppListPresenterImpl::Dismiss() { @@ -119,6 +119,7 @@ if (view_->GetWidget()->IsActive()) view_->GetWidget()->Deactivate(); + view_delegate_->ViewClosing(); presenter_delegate_->OnDismissed(); ScheduleAnimation(); base::RecordAction(base::UserMetricsAction("Launcher_Dismiss"));
diff --git a/ui/app_list/presenter/app_list_presenter_impl.h b/ui/app_list/presenter/app_list_presenter_impl.h index ad748cc8..5c957af 100644 --- a/ui/app_list/presenter/app_list_presenter_impl.h +++ b/ui/app_list/presenter/app_list_presenter_impl.h
@@ -125,6 +125,9 @@ // Responsible for laying out the app list UI. std::unique_ptr<AppListPresenterDelegate> presenter_delegate_; + // The view delegate owned by AppListService. + AppListViewDelegate* view_delegate_ = nullptr; + // Whether we should show or hide app list widget. bool is_visible_ = false;
diff --git a/ui/app_list/test/app_list_test_view_delegate.cc b/ui/app_list/test/app_list_test_view_delegate.cc index 5d1cc4d..36b7741 100644 --- a/ui/app_list/test/app_list_test_view_delegate.cc +++ b/ui/app_list/test/app_list_test_view_delegate.cc
@@ -33,11 +33,11 @@ return search_model_.get(); } -void AppListTestViewDelegate::OpenSearchResult(SearchResult* result, +void AppListTestViewDelegate::OpenSearchResult(const std::string& result_id, int event_flags) { const SearchModel::SearchResults* results = search_model_->results(); for (size_t i = 0; i < results->item_count(); ++i) { - if (results->GetItemAt(i) == result) { + if (results->GetItemAt(i)->id() == result_id) { open_search_result_counts_[i]++; break; }
diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h index c8fe7ac..c484934 100644 --- a/ui/app_list/test/app_list_test_view_delegate.h +++ b/ui/app_list/test/app_list_test_view_delegate.h
@@ -47,12 +47,11 @@ AppListModel* GetModel() override; SearchModel* GetSearchModel() override; void StartSearch(const base::string16& raw_query) override {} - void OpenSearchResult(SearchResult* result, - int event_flags) override; - void InvokeSearchResultAction(SearchResult* result, + void OpenSearchResult(const std::string& result_id, int event_flags) override; + void InvokeSearchResultAction(const std::string& result_id, int action_index, int event_flags) override {} - void ViewShown() override {} + void ViewShown(int64_t display_id) override {} void Dismiss() override; void ViewClosing() override {} void GetWallpaperProminentColors(
diff --git a/ui/app_list/test/test_search_result.cc b/ui/app_list/test/test_search_result.cc index 8339606..33969e45 100644 --- a/ui/app_list/test/test_search_result.cc +++ b/ui/app_list/test/test_search_result.cc
@@ -12,6 +12,10 @@ TestSearchResult::~TestSearchResult() { } +void TestSearchResult::set_result_id(const std::string& id) { + set_id(id); +} + std::unique_ptr<SearchResult> TestSearchResult::Duplicate() const { NOTREACHED(); return nullptr;
diff --git a/ui/app_list/test/test_search_result.h b/ui/app_list/test/test_search_result.h index 6102ec03..24d66e5 100644 --- a/ui/app_list/test/test_search_result.h +++ b/ui/app_list/test/test_search_result.h
@@ -6,6 +6,7 @@ #define UI_APP_LIST_TEST_TEST_SEARCH_RESULT_H_ #include <memory> +#include <string> #include "ash/app_list/model/search/search_result.h" #include "base/macros.h" @@ -18,6 +19,8 @@ TestSearchResult(); ~TestSearchResult() override; + void set_result_id(const std::string& id); + // SearchResult: std::unique_ptr<SearchResult> Duplicate() const override;
diff --git a/ui/app_list/views/search_result_answer_card_view.cc b/ui/app_list/views/search_result_answer_card_view.cc index 41dca99..7cd446d 100644 --- a/ui/app_list/views/search_result_answer_card_view.cc +++ b/ui/app_list/views/search_result_answer_card_view.cc
@@ -109,7 +109,7 @@ if (search_result_) { RecordSearchResultOpenSource(search_result_, view_delegate_->GetModel(), view_delegate_->GetSearchModel()); - view_delegate_->OpenSearchResult(search_result_, event.flags()); + view_delegate_->OpenSearchResult(search_result_->id(), event.flags()); } }
diff --git a/ui/app_list/views/search_result_list_view.cc b/ui/app_list/views/search_result_list_view.cc index 09254ab..1809f27 100644 --- a/ui/app_list/views/search_result_list_view.cc +++ b/ui/app_list/views/search_result_list_view.cc
@@ -160,7 +160,7 @@ if (view_delegate_ && view->result()) { RecordSearchResultOpenSource(view->result(), view_delegate_->GetModel(), view_delegate_->GetSearchModel()); - view_delegate_->OpenSearchResult(view->result(), event_flags); + view_delegate_->OpenSearchResult(view->result()->id(), event_flags); } } @@ -168,7 +168,7 @@ size_t action_index, int event_flags) { if (view_delegate_ && view->result()) { - view_delegate_->InvokeSearchResultAction(view->result(), action_index, + view_delegate_->InvokeSearchResultAction(view->result()->id(), action_index, event_flags); } }
diff --git a/ui/app_list/views/search_result_tile_item_list_view_unittest.cc b/ui/app_list/views/search_result_tile_item_list_view_unittest.cc index 56c92b5..fcf3ea6 100644 --- a/ui/app_list/views/search_result_tile_item_list_view_unittest.cc +++ b/ui/app_list/views/search_result_tile_item_list_view_unittest.cc
@@ -74,6 +74,7 @@ for (int i = 0; i < kInstalledApps; ++i) { std::unique_ptr<TestSearchResult> result = std::make_unique<TestSearchResult>(); + result->set_result_id(base::StringPrintf("InstalledApp %d", i)); result->set_display_type(SearchResult::DISPLAY_TILE); result->set_result_type(SearchResult::RESULT_INSTALLED_APP); result->set_title( @@ -86,6 +87,7 @@ for (int i = 0; i < kPlayStoreApps; ++i) { std::unique_ptr<TestSearchResult> result = std::make_unique<TestSearchResult>(); + result->set_result_id(base::StringPrintf("PlayStoreApp %d", i)); result->set_display_type(SearchResult::DISPLAY_TILE); result->set_result_type(SearchResult::RESULT_PLAYSTORE_APP); result->set_title(
diff --git a/ui/app_list/views/search_result_tile_item_view.cc b/ui/app_list/views/search_result_tile_item_view.cc index 0d602311..4c3348c 100644 --- a/ui/app_list/views/search_result_tile_item_view.cc +++ b/ui/app_list/views/search_result_tile_item_view.cc
@@ -260,7 +260,7 @@ RecordSearchResultOpenSource(item_, view_delegate_->GetModel(), view_delegate_->GetSearchModel()); - view_delegate_->OpenSearchResult(item_, event.flags()); + view_delegate_->OpenSearchResult(item_->id(), event.flags()); } void SearchResultTileItemView::GetAccessibleNodeData( @@ -293,7 +293,7 @@ RecordSearchResultOpenSource(item_, view_delegate_->GetModel(), view_delegate_->GetSearchModel()); - view_delegate_->OpenSearchResult(item_, event.flags()); + view_delegate_->OpenSearchResult(item_->id(), event.flags()); return true; }
diff --git a/ui/aura/window.cc b/ui/aura/window.cc index 063a286..c2eb8cc 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc
@@ -1032,23 +1032,18 @@ bool visible) { if (!NotifyWindowVisibilityChangedAtReceiver(target, visible)) return false; // |this| was deleted. - std::set<const Window*> child_already_processed; - bool child_destroyed = false; - do { - child_destroyed = false; - for (Window::Windows::const_iterator it = children_.begin(); - it != children_.end(); ++it) { - if (!child_already_processed.insert(*it).second) - continue; - if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) { - // |*it| was deleted, |it| is invalid and |children_| has changed. - // We exit the current for-loop and enter a new one. - child_destroyed = true; - break; - } - } - } while (child_destroyed); - return true; + + WindowTracker this_tracker; + this_tracker.Add(this); + // Copy |children_| in case iterating mutates |children_|, or destroys an + // existing child. + WindowTracker children(children_); + + while (!this_tracker.windows().empty() && !children.windows().empty()) + children.Pop()->NotifyWindowVisibilityChangedDown(target, visible); + + const bool this_still_valid = !this_tracker.windows().empty(); + return this_still_valid; } void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc index c9aec7a..ad4adf87 100644 --- a/ui/aura/window_unittest.cc +++ b/ui/aura/window_unittest.cc
@@ -32,6 +32,7 @@ #include "ui/aura/window_delegate.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_observer.h" +#include "ui/aura/window_tracker.h" #include "ui/aura/window_tree_host.h" #include "ui/base/class_property.h" #include "ui/base/hit_test.h" @@ -113,6 +114,7 @@ namespace aura { namespace test { +namespace { class WindowTest : public AuraTestBaseWithType { public: @@ -140,8 +142,6 @@ DISALLOW_COPY_AND_ASSIGN(WindowTest); }; -namespace { - // Used for verifying destruction methods are invoked. class DestroyTrackingDelegateImpl : public TestWindowDelegate { public: @@ -316,8 +316,6 @@ window->SetBounds(bounds); } -} // namespace - TEST_P(WindowTest, GetChildById) { std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window())); std::unique_ptr<Window> w11(CreateTestWindowWithId(11, w1.get())); @@ -1673,8 +1671,6 @@ EXPECT_EQ(nullptr, w->GetNativeWindowProperty(native_prop_key)); } -namespace { - class DeletionTestLayoutManager : public LayoutManager { public: explicit DeletionTestLayoutManager(DeletionTracker* tracker) @@ -1696,8 +1692,6 @@ DISALLOW_COPY_AND_ASSIGN(DeletionTestLayoutManager); }; -} // namespace - TEST_P(WindowTest, DeleteLayoutManagerBeforeOwnedProps) { DeletionTracker tracker; { @@ -2696,8 +2690,6 @@ EXPECT_EQ(NULL, w2->parent()); } -namespace { - // Used By DeleteWindowFromOnWindowDestroyed. Destroys a Window from // OnWindowDestroyed(). class OwningWindowDelegate : public TestWindowDelegate { @@ -2716,8 +2708,6 @@ DISALLOW_COPY_AND_ASSIGN(OwningWindowDelegate); }; -} // namespace - // Creates a window with two child windows. When the first child window is // destroyed (WindowDelegate::OnWindowDestroyed) it deletes the second child. // This synthesizes BrowserView and the status bubble. Both are children of the @@ -2737,7 +2727,52 @@ parent.reset(); } -namespace { +// WindowObserver implementation that deletes a window in +// OnWindowVisibilityChanged(). +class DeleteOnVisibilityChangedObserver : public WindowObserver { + public: + // |to_observe| is the Window this is added as an observer to. When + // OnWindowVisibilityChanged() is called |to_delete| is deleted. + explicit DeleteOnVisibilityChangedObserver(Window* to_observe, + Window* to_delete) + : to_observe_(to_observe), to_delete_(to_delete) { + to_observe_->AddObserver(this); + } + ~DeleteOnVisibilityChangedObserver() override { + // OnWindowVisibilityChanged() should have been called. + DCHECK(!to_delete_); + } + + // WindowObserver: + void OnWindowVisibilityChanged(Window* window, bool visible) override { + to_observe_->RemoveObserver(this); + delete to_delete_; + to_delete_ = nullptr; + } + + private: + Window* to_observe_; + Window* to_delete_; + + DISALLOW_COPY_AND_ASSIGN(DeleteOnVisibilityChangedObserver); +}; + +TEST_P(WindowTest, DeleteParentWindowFromOnWindowVisibiltyChanged) { + WindowTracker tracker; + Window* root = CreateTestWindowWithId(0, nullptr); + tracker.Add(root); + Window* child1 = CreateTestWindowWithId(0, root); + tracker.Add(child1); + tracker.Add(CreateTestWindowWithId(0, root)); + + // This deletes |root| (the parent) when OnWindowVisibilityChanged() is + // received by |child1|. + DeleteOnVisibilityChangedObserver deletion_observer(child1, root); + // The Hide() calls trigger deleting |root|, which should delete the whole + // tree. + root->Hide(); + EXPECT_TRUE(tracker.windows().empty()); +} // Used by DelegateNotifiedAsBoundsChange to verify OnBoundsChanged() is // invoked. @@ -2763,8 +2798,6 @@ DISALLOW_COPY_AND_ASSIGN(BoundsChangeDelegate); }; -} // namespace - // Verifies the delegate is notified when the actual bounds of the layer // change. TEST_P(WindowTest, DelegateNotifiedAsBoundsChange) { @@ -2843,8 +2876,6 @@ EXPECT_NE("0,0 100x100", window->layer()->bounds().ToString()); } -namespace { - // Used by AddChildNotifications to track notification counts. class AddChildNotificationsObserver : public WindowObserver { public: @@ -2871,8 +2902,6 @@ DISALLOW_COPY_AND_ASSIGN(AddChildNotificationsObserver); }; -} // namespace - // Assertions around when root window notifications are sent. TEST_P(WindowTest, AddChildNotifications) { AddChildNotificationsObserver observer; @@ -3094,8 +3123,6 @@ } } -namespace { - class TestLayerAnimationObserver : public ui::LayerAnimationObserver { public: TestLayerAnimationObserver() @@ -3130,8 +3157,6 @@ DISALLOW_COPY_AND_ASSIGN(TestLayerAnimationObserver); }; -} // namespace - TEST_P(WindowTest, WindowDestroyCompletesAnimations) { ui::ScopedAnimationDurationScaleMode test_duration_mode( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); @@ -3248,5 +3273,6 @@ BackendType::MUS, BackendType::MUS_HOSTING_VIZ)); +} // namespace } // namespace test } // namespace aura
diff --git a/ui/base/ui_features.gni b/ui/base/ui_features.gni index eedf40a..708a8f8 100644 --- a/ui/base/ui_features.gni +++ b/ui/base/ui_features.gni
@@ -20,6 +20,11 @@ # Set to true to if mus (aka the UI service) is enabled. Use --mus (or --mash # in chrome code) to start in mus/mash. enable_mus = is_chromeos + + # Optimize parts of Chrome's UI written with web technologies (HTML/CSS/JS) + # for runtime performance purposes. This does more work at compile time for + # speed benefits at runtime (so we skip in debug builds). + optimize_webui = !is_debug } enable_hidpi = is_mac || is_win || is_linux
diff --git a/ui/chromeos/OWNERS b/ui/chromeos/OWNERS index 32cebd5..d72cae1 100644 --- a/ui/chromeos/OWNERS +++ b/ui/chromeos/OWNERS
@@ -5,3 +5,6 @@ # Accessibility per-file touch_exploration_controller*=dmazzoni@chromium.org + +# grdp files +per-file keyboard_shortcut_viewer_strings.grdp=file://ui/chromeos/ksv/OWNERS
diff --git a/ui/resources/BUILD.gn b/ui/resources/BUILD.gn index ac466919a..8286ba5 100644 --- a/ui/resources/BUILD.gn +++ b/ui/resources/BUILD.gn
@@ -5,6 +5,7 @@ import("//build/config/jumbo.gni") import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") +import("//ui/base/ui_features.gni") group("resources") { public_deps = [ @@ -35,6 +36,7 @@ } grit("webui_resources_grd") { + defines = [ "optimize_webui=$optimize_webui" ] source = "../webui/resources/webui_resources.grd" # The .grd contains references to generated files.
diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc index e7f7503..84b0514 100644 --- a/ui/views/controls/webview/webview.cc +++ b/ui/views/controls/webview/webview.cc
@@ -54,11 +54,11 @@ void WebView::SetWebContents(content::WebContents* replacement) { if (replacement == web_contents()) return; - SetCrashedOverlayView(nullptr); DetachWebContents(); WebContentsObserver::Observe(replacement); // web_contents() now returns |replacement| from here onwards. - UpdateCrashedOverlayView(); + SetFocusBehavior(web_contents() ? FocusBehavior::ALWAYS + : FocusBehavior::NEVER); if (wc_owner_.get() != replacement) wc_owner_.reset(); if (embed_fullscreen_widget_mode_enabled_) { @@ -91,25 +91,6 @@ holder_->set_resize_background_color(resize_background_color); } -void WebView::SetCrashedOverlayView(View* crashed_overlay_view) { - if (crashed_overlay_view_ == crashed_overlay_view) - return; - - if (crashed_overlay_view_) { - RemoveChildView(crashed_overlay_view_); - if (!crashed_overlay_view_->owned_by_client()) - delete crashed_overlay_view_; - } - - crashed_overlay_view_ = crashed_overlay_view; - if (crashed_overlay_view_) { - AddChildView(crashed_overlay_view_); - crashed_overlay_view_->SetBoundsRect(gfx::Rect(size())); - } - - UpdateCrashedOverlayView(); -} - //////////////////////////////////////////////////////////////////////////////// // WebView, View overrides: @@ -130,9 +111,6 @@ } void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) { - if (crashed_overlay_view_) - crashed_overlay_view_->SetBoundsRect(gfx::Rect(size())); - // In most cases, the holder is simply sized to fill this WebView's bounds. // Only WebContentses that are in fullscreen mode and being screen-captured // will engage the special layout/sizing behavior. @@ -203,12 +181,12 @@ } void WebView::OnFocus() { - if (web_contents() && !web_contents()->IsCrashed()) + if (web_contents()) web_contents()->Focus(); } void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) { - if (web_contents() && !web_contents()->IsCrashed()) + if (web_contents()) web_contents()->FocusThroughTabTraversal(reverse); } @@ -217,7 +195,7 @@ } gfx::NativeViewAccessible WebView::GetNativeViewAccessible() { - if (web_contents() && !web_contents()->IsCrashed()) { + if (web_contents()) { content::RenderWidgetHostView* host_view = web_contents()->GetRenderWidgetHostView(); if (host_view) @@ -238,12 +216,10 @@ // WebView, content::WebContentsObserver implementation: void WebView::RenderViewReady() { - UpdateCrashedOverlayView(); NotifyAccessibilityWebContentsChanged(); } void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) { - UpdateCrashedOverlayView(); NotifyAccessibilityWebContentsChanged(); } @@ -288,7 +264,6 @@ } void WebView::RenderProcessGone(base::TerminationStatus status) { - UpdateCrashedOverlayView(); NotifyAccessibilityWebContentsChanged(); } @@ -342,22 +317,6 @@ NotifyAccessibilityWebContentsChanged(); } -void WebView::UpdateCrashedOverlayView() { - if (web_contents() && web_contents()->IsCrashed() && crashed_overlay_view_) { - SetFocusBehavior(FocusBehavior::NEVER); - holder_->SetVisible(false); - crashed_overlay_view_->SetVisible(true); - return; - } - - SetFocusBehavior(web_contents() ? FocusBehavior::ALWAYS - : FocusBehavior::NEVER); - - if (crashed_overlay_view_) - crashed_overlay_view_->SetVisible(false); - holder_->SetVisible(true); -} - void WebView::NotifyAccessibilityWebContentsChanged() { if (web_contents()) NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged, false);
diff --git a/ui/views/controls/webview/webview.h b/ui/views/controls/webview/webview.h index afdd0a03..73ad929 100644 --- a/ui/views/controls/webview/webview.h +++ b/ui/views/controls/webview/webview.h
@@ -79,11 +79,6 @@ // by default. void SetResizeBackgroundColor(SkColor resize_background_color); - // If provided, this View will be shown in place of the web contents - // when the web contents is in a crashed state. This is cleared automatically - // if the web contents is changed. - void SetCrashedOverlayView(View* crashed_overlay_view); - // When used to host UI, we need to explicitly allow accelerators to be // processed. Default is false. void set_allow_accelerators(bool allow_accelerators) { @@ -145,7 +140,6 @@ void AttachWebContents(); void DetachWebContents(); void ReattachForFullscreenChange(bool enter_fullscreen); - void UpdateCrashedOverlayView(); void NotifyAccessibilityWebContentsChanged(); // Create a regular or test web contents (based on whether we're running @@ -164,7 +158,6 @@ bool is_embedding_fullscreen_widget_; content::BrowserContext* browser_context_; bool allow_accelerators_; - View* crashed_overlay_view_ = nullptr; DISALLOW_COPY_AND_ASSIGN(WebView); };
diff --git a/ui/views/controls/webview/webview_unittest.cc b/ui/views/controls/webview/webview_unittest.cc index 686cf05..2ca7683 100644 --- a/ui/views/controls/webview/webview_unittest.cc +++ b/ui/views/controls/webview/webview_unittest.cc
@@ -485,52 +485,4 @@ webview.reset(); } -// Test that the specified crashed overlay view is shown when a WebContents -// is in a crashed state. -TEST_F(WebViewUnitTest, CrashedOverlayView) { - content::WebContents* web_contents = web_view()->GetWebContents(); - View* crashed_overlay_view = new View(); - web_view()->SetCrashedOverlayView(crashed_overlay_view); - EXPECT_FALSE(crashed_overlay_view->IsDrawn()); - - // Normally when a renderer crashes, the WebView will learn about it - // automatically via WebContentsObserver. Since this is a test - // WebContents, simulate that by calling SetIsCrashed and then - // explicitly calling RenderViewDeleted on the WebView to trigger it - // to swap in the crashed overlay view. - web_contents->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1); - EXPECT_TRUE(web_contents->IsCrashed()); - static_cast<content::WebContentsObserver*>(web_view()) - ->RenderViewDeleted(nullptr); - EXPECT_TRUE(crashed_overlay_view->IsDrawn()); -} - -// Test that a crashed overlay view isn't deleted if it's owned by client. -TEST_F(WebViewUnitTest, CrashedOverlayViewOwnedbyClient) { - const std::unique_ptr<content::WebContents> web_contents(CreateWebContents()); - std::unique_ptr<WebView> web_view( - new WebView(web_contents->GetBrowserContext())); - View* contents_view = top_level_widget()->GetContentsView(); - contents_view->AddChildView(web_view.get()); - web_view->SetWebContents(web_contents.get()); - - View* crashed_overlay_view = new View(); - crashed_overlay_view->set_owned_by_client(); - web_view->SetCrashedOverlayView(crashed_overlay_view); - EXPECT_FALSE(crashed_overlay_view->IsDrawn()); - - // Simulate a renderer crash (see above). - web_contents->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1); - EXPECT_TRUE(web_contents->IsCrashed()); - static_cast<content::WebContentsObserver*>(web_view.get()) - ->RenderViewDeleted(nullptr); - EXPECT_TRUE(crashed_overlay_view->IsDrawn()); - - web_view->SetCrashedOverlayView(nullptr); - web_view.reset(); - - // This shouldn't crash, we still own this. - delete crashed_overlay_view; -} - } // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index cde45a41..99b432f 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -362,7 +362,7 @@ View* view_for_activation = focus_manager->GetFocusedView() ? focus_manager->GetFocusedView() : focus_manager->GetStoredFocusView(); - if (!view_for_activation || !view_for_activation->GetWidget()) { + if (!view_for_activation) { view_for_activation = GetWidget()->GetRootView(); } else if (view_for_activation == focus_manager->GetStoredFocusView()) { // When desktop native widget has modal transient child, we don't
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html b/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html index dc8592f..a71d029 100644 --- a/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html +++ b/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html
@@ -13,7 +13,7 @@ <template> <style include="cr-hidden-style iron-flex"> dialog { - @apply(--bluetooth-dialog-style); + @apply --bluetooth-dialog-style; } #pairing {
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config.js b/ui/webui/resources/cr_components/chromeos/network/network_config.js index f474bfc..aafbad6 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_config.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_config.js
@@ -1181,8 +1181,10 @@ setVpnIPsecProperties_: function(propertiesToSet) { var vpn = propertiesToSet.VPN; assert(vpn.IPsec); - if (vpn.IPsec.AuthenticationType == CrOnc.IPsecAuthenticationType.CERT) + if (vpn.IPsec.AuthenticationType == CrOnc.IPsecAuthenticationType.CERT) { + vpn.IPsec.ClientCertType = 'PKCS11Id'; vpn.IPsec.ClientCertPKCS11Id = this.getUserCertPkcs11Id_(); + } vpn.IPsec.IKEVersion = 1; vpn.IPsec.SaveCredentials = this.vpnSaveCredentials_; vpn.L2TP.SaveCredentials = this.vpnSaveCredentials_;
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html b/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html index f574252..44388997 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html
@@ -9,7 +9,7 @@ <template> <style include="network-shared cr-hidden-style iron-flex"> iron-icon { - @apply(--cr-actionable); + @apply --cr-actionable; margin: 5px; }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html b/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html index 3d6b9ee..7c2deb9 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html
@@ -19,7 +19,7 @@ } .property-box { - @apply(--cr-section); + @apply --cr-section; border-top: none; min-height: var(--cr-section-min-height); padding: 0; @@ -59,7 +59,7 @@ } .secondary { - @apply(--cr-secondary-text); + @apply --cr-secondary-text; } paper-input-container {
diff --git a/ui/webui/resources/cr_components/cr_components_resources.grdp b/ui/webui/resources/cr_components/cr_components_resources.grdp index 3b4e57c..1e198676 100644 --- a/ui/webui/resources/cr_components/cr_components_resources.grdp +++ b/ui/webui/resources/cr_components/cr_components_resources.grdp
@@ -96,8 +96,9 @@ type="chrome_html" compress="gzip" /> </if> - <if expr="chromeos"> - <!-- Chrome OS Custom Elements --> + <if expr="chromeos and not optimize_webui"> + <!-- Chrome OS Custom Elements. When optimize_webui is true these are --> + <!-- vulcanized and are not included individually. --> <structure name="IDR_WEBUI_CHROMEOS_BLUETOOTH_DIALOG_HTML" file="cr_components/chromeos/bluetooth_dialog.html" type="chrome_html"
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html index edd6e1b..68cb78f 100644 --- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html +++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
@@ -29,7 +29,7 @@ flex-direction: column; max-height: 100vh; overflow: auto; - @apply(--cr-dialog-wrapper); + @apply --cr-dialog-wrapper; } /* When needing to flex, force .body-container alone to shrink. */ @@ -50,7 +50,7 @@ :host ::slotted([slot=body]) { padding: 12px 16px; - @apply(--cr-dialog-body); + @apply --cr-dialog-body; } :host ::slotted([slot=title]) { @@ -58,7 +58,7 @@ font-size: calc(15 / 13 * 100%); line-height: 1; padding: 16px 16px; - @apply(--cr-dialog-title); + @apply --cr-dialog-title; } :host ::slotted([slot=button-container]) { @@ -85,7 +85,7 @@ min-height: 60px; /* Minimum reasonably usable height. */ overflow: auto; - @apply(--cr-dialog-body-container); + @apply --cr-dialog-body-container; } .body-container.bottom-scrollable {
diff --git a/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html b/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html index d2a2dddc..e313458 100644 --- a/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html +++ b/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html
@@ -11,7 +11,7 @@ } button[is=paper-icon-button-light] { - @apply(--cr-paper-icon-button-margin); + @apply --cr-paper-icon-button-margin; } #outer {
diff --git a/ui/webui/resources/cr_elements/cr_icons_css.html b/ui/webui/resources/cr_elements/cr_icons_css.html index f207914..f8dc56c8 100644 --- a/ui/webui/resources/cr_elements/cr_icons_css.html +++ b/ui/webui/resources/cr_elements/cr_icons_css.html
@@ -11,7 +11,7 @@ button[is='paper-icon-button-light'], .cr-icon { - @apply(--cr-paper-icon-button-margin); + @apply --cr-paper-icon-button-margin; background-position: center; background-repeat: no-repeat; background-size: var(--cr-icon-size);
diff --git a/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html b/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html index 4f6115b4..97bb3cc6 100644 --- a/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html +++ b/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html
@@ -65,7 +65,7 @@ } #subLabel { - /* TODO(dschuyler): replace with: @apply(--cr-secondary-text); */ + /* TODO(dschuyler): replace with: @apply --cr-secondary-text; */ color: var(--paper-grey-600); font-weight: 400; }
diff --git a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html index 29b9923..bc13ad1d 100644 --- a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html +++ b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
@@ -12,7 +12,7 @@ --avatar-spacing: 24px; display: inline-flex; - @apply(--avatar-selector); + @apply --avatar-selector; } #avatar-grid .avatar { @@ -33,7 +33,7 @@ padding: 0; width: var(--avatar-size); - @apply(--avatar-selector-avatar); + @apply --avatar-selector-avatar; } #avatar-grid .avatar.iron-selected {
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html index 24ca911..063e1fd 100644 --- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html +++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
@@ -40,7 +40,7 @@ } paper-spinner-lite { - @apply(--cr-icon-height-width); + @apply --cr-icon-height-width; --paper-spinner-color: white; margin: 0 6px; opacity: 0;
diff --git a/ui/webui/resources/cr_elements/paper_toggle_style_css.html b/ui/webui/resources/cr_elements/paper_toggle_style_css.html index 95581fd..44260f55 100644 --- a/ui/webui/resources/cr_elements/paper_toggle_style_css.html +++ b/ui/webui/resources/cr_elements/paper_toggle_style_css.html
@@ -28,7 +28,7 @@ --paper-toggle-button-checked-bar: var(--cr-toggle-bar-size); --paper-toggle-button-checked-bar-color: var(--cr-toggle-color); --paper-toggle-button-checked-button: { - @apply(--cr-toggle-button-size); + @apply --cr-toggle-button-size; transform: translate(18px, 0); }; --paper-toggle-button-checked-button-color: var(--cr-toggle-color);
diff --git a/ui/webui/resources/cr_elements/shared_style_css.html b/ui/webui/resources/cr_elements/shared_style_css.html index f3bcb9e..090a611 100644 --- a/ui/webui/resources/cr_elements/shared_style_css.html +++ b/ui/webui/resources/cr_elements/shared_style_css.html
@@ -36,7 +36,7 @@ } [actionable] { - @apply(--cr-actionable); + @apply --cr-actionable; } .subpage-arrow, @@ -71,8 +71,8 @@ border-bottom-color: var(--google-grey-300); } [scrollable] iron-list > :not(.no-outline):focus { - @apply(--cr-list-item-focus); - @apply(--cr-selectable-focus); + @apply --cr-list-item-focus; + @apply --cr-selectable-focus; } .scroll-container { @@ -83,15 +83,15 @@ [selectable]:focus, [selectable] > :focus { - @apply(--cr-selectable-focus); + @apply --cr-selectable-focus; } [selectable] > * { - @apply(--cr-actionable); + @apply --cr-actionable; } /** Styles for elements that implement the CrContainerShadowBehavior */ #cr-container-shadow { - @apply(--cr-container-shadow); + @apply --cr-container-shadow; } #cr-container-shadow.has-shadow {
diff --git a/ui/webui/resources/html/action_link_css.html b/ui/webui/resources/html/action_link_css.html index 9ece1d5..904395b 100644 --- a/ui/webui/resources/html/action_link_css.html +++ b/ui/webui/resources/html/action_link_css.html
@@ -6,7 +6,7 @@ <template> <style> [is='action-link'] { - @apply(--cr-actionable); + @apply --cr-actionable; display: inline-block; text-decoration: none; }